0022-0026 教程学习笔记
0022 Nginx与高可用
1.什么是分布式?
不同模块,部署在不同机器上,解决的是高并发的问题
2.什么是集群?
将一个项目部署在多个节点上
3.什么是SpringCloud? 是一个rpc微服务框架,提供注册服务,发现服务,断路器,网关,自动配置
0024 zookeeper
1.Zookeeper是分布式协调工具,可以做协调,统一配置,分布式共享锁,统一名称服务
2.Zookeeper集群:一个leader,多个follower组成的集群
3.zookeeper存储结构: 以节点(node)方式存储,
4.zookeeper服务领域:主从协调,服务器节点动态上下线,统一配置管理,分布式共享锁,统一命名服务
5.分布式锁解决思路
分布式锁使用zk,在zk上创建一个临时节点(有效期) ,使用临时节点作为锁,因为节点不允许重复。
如果能创建节点成功,生成订单号,如果创建节点失败,等待。临时节点zk关闭,释放锁,其他节点就可以重新生成订单号。
为什么不用数据库? 因为数据库会操作Io,并且容易产生死锁
redis:redis自定义失败
#####生成订单号###### import java.text.SimpleDateFormat; import java.util.Date; //生成订单号 public class OrderNumGenerator { private static int count = 0; //生成订单号 public String getOrderNumber() { SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); return smt.format(new Date()) + "-" + ++count; } } #####订单业务逻辑###### public class OrderService implements Runnable { private OrderNumGenerator orderNumGenerator = new OrderNumGenerator(); private static Object oj = new Object(); private Lock lock = new ZookeeperDistrbuteLock(); public void run() { getNumber(); } public void getNumber() { // synchronized (oj) { lock.getLock(); String orderNumber = orderNumGenerator.getOrderNumber(); System.out.println("获取订单号:" + orderNumber); lock.unLock(); // } } public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(new OrderService()).start(); } } } #####lock接口 ###### public interface Lock { // 获取锁 public void getLock(); // 释放锁 public void unLock(); } #####ZookeeperAbstractLock抽象类接口 ###### public abstract class ZookeeperAbstractLock implements Lock { private static final String CONNECT_ADDRES = "192.168.110.159:2181,192.168.110.160:2181,192.168.110.162:2181"; protected ZkClient zkClient = new ZkClient(CONNECT_ADDRES); protected String PATH = "/lock"; public void getLock() { // 如果当前节点已经存在,则等待 if (tryLock()) { System.out.println("获取到锁 get"); } else { // 等待 waitLock(); // 重新获取锁 getLock(); } } protected abstract void waitLock(); protected abstract boolean tryLock(); public void unLock() { if (zkClient != null) { zkClient.close(); } System.out.println("已经释放锁..."); } #####ZookeeperAbstractLock抽象类接口 ###### //实现锁 public class ZookeeperDistrbuteLock extends ZookeeperAbstractLock { private CountDownLatch countDownLatch = new CountDownLatch(1); @Override protected boolean tryLock() { try { zkClient.createEphemeral(PATH); // 创建成功 return true; } catch (Exception e) { // 创建失败 return false; } } @Override protected void waitLock() { try { IZkDataListener iZkDataListener = new IZkDataListener() { public void handleDataDeleted(String path) throws Exception { // 唤醒等待线程, 继续往下走. if (countDownLatch != null) { countDownLatch.countDown(); } } public void handleDataChange(String path, Object data) throws Exception { } }; // 注册到zk监听中 zkClient.subscribeDataChanges(PATH, iZkDataListener); if (zkClient.exists(PATH)) { countDownLatch = new CountDownLatch(1); // 等待 countDownLatch.await(); } // 删除事件通知 zkClient.unsubscribeDataChanges(PATH, iZkDataListener); } catch (Exception e) { // TODO: handle exception } } }
解决跨域的4中方案:
1.jsonp 缺点:只能支持get
2.设置响应头 ,referer
3.通过httpclient转发,缺点:比较麻烦,耗资源
4.nginx(反向代理) SpringCloud(API ZUUL)
0025 Dobbo
Dubbo架构图
利用zookeeper中的watch方法监听生产者的变化,并通知到消费者,redis也有这个机制,所以redis也可以实现这个功能