zoukankan      html  css  js  c++  java
  • ZooKeeper实践:(1)集群管理

    前言:

           随着业务的扩大,用户的增多,访问量的增加,单机模式已经不能支撑,从而出现了从单机模式->垂直应用模式->集群模式,集群模式诞生了,伴随着一堆问题也油然而生,Master怎么选举,机器故障及时移除集群,添加机器了如何及时的感应到,Zookeeper不仅能维护当前的集群服务状态,还能及时的选出master,它们的实现方式都是在Zookeeper上面注册一个EPHEMERAL目录节点,在创建目录的父目录上面调用getChildren(String path,boolean watch)设置watch为true,注册watcher事件,由于是临时节点,当服务器出现问题造成session丢失,相对应的目录节点随之删除,Children节点发生变化,就会调用前面注册的watcher,使集群内的每个节点都得到新的集群信息。反之,新增节点也是这样。

    注:master选举,不同之处是注册一个EPHEMERAL_SEQUENTIAL 目录节点,我们可以选择最小编号为master,实现了动态选择master,避免master出现单点故障

    一、架构体系

         

    二:模拟代码

          监控类: 

    package com.zk.config.manager;
    
    import java.io.IOException;
    import java.util.Collections;
    import java.util.List;
    import java.util.concurrent.CountDownLatch;
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    import org.apache.zookeeper.Watcher.Event.EventType;
    import org.apache.zookeeper.Watcher.Event.KeeperState;
    import org.apache.zookeeper.ZooDefs.Ids;
    
    public class AppRegister {
    
    	private CountDownLatch connectedSemaphore = new CountDownLatch(1);
    	private ZooKeeper zooKeeper;
    	private Object lock = new Object();
    	private String ip;
    
    	private String rootConfig;
    
    	public AppRegister(String ip, String root) {
    		this.ip = ip;
    		this.rootConfig = root;
    		this.zooKeeper = connectZookeeper();
    
    	}
    
    	public ZooKeeper connectZookeeper() {
    		synchronized (lock) {
    			if (zooKeeper == null) {
    				try {
    					zooKeeper = new ZooKeeper("192.168.1.1:2181", 5000, new Watcher() {
    						public void process(WatchedEvent event) {
    							if (KeeperState.SyncConnected == event.getState()) {
    								if (EventType.None == event.getType() && null == event.getPath()) {
    									try {
    										connectedSemaphore.countDown();
    										zooKeeper.getChildren(rootConfig, true);
    										zooKeeper.create(rootConfig + "/" + ip, ip.getBytes(), Ids.OPEN_ACL_UNSAFE,
    												CreateMode.EPHEMERAL_SEQUENTIAL);
    									} catch (KeeperException e) {
    										e.printStackTrace();
    									} catch (InterruptedException e) {
    										e.printStackTrace();
    									}
    								} else if (EventType.NodeChildrenChanged == event.getType()) {
    									try {
    										List<String> childrenList = zooKeeper.getChildren(rootConfig, true);
    										System.out.println("节点变化了:" + childrenList);
    										Collections.sort(childrenList);
    										System.out.println("我是master了:" + childrenList.get(0));
    									} catch (KeeperException e) {
    										e.printStackTrace();
    									} catch (InterruptedException e) {
    										e.printStackTrace();
    									}
    
    								}
    
    							}
    						}
    					}
    
    					);
    					connectedSemaphore.await();
    				} catch (IOException e) {
    					e.printStackTrace();
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    
    			}
    		}
    		return zooKeeper;
    	}
    }
    

     模拟程序:

    package com.zk.config.manager;
    
    public class AppMonitor {
    	private final static String rootConfig = "/AppCluster";
    	public static void main(String[] args) throws InterruptedException {
    		
    		/**
    		 * 新增机器,选举master
    		 */
    		addHost();
    		
    		Thread.sleep(Integer.MAX_VALUE);
    	}
    	
    	private static void  addHost()
    	{
    		new Thread(new Runnable() {
    			public void run() {
    				new AppRegister("192.168.1.1", rootConfig);
    			}
    		}).start();
    
    		new Thread(new Runnable() {
    			public void run() {
    				try {
    
    					Thread.sleep(2000);
    					new AppRegister("192.168.1.2", rootConfig);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}).start();
    	
    	}
    
    }
    

     运行结果:

    节点变化了:[192.168.1.10000000029]
    我是master了:192.168.1.10000000029
    节点变化了:[192.168.1.20000000030, 192.168.1.10000000029]
    我是master了:192.168.1.10000000029
    节点变化了:[192.168.1.20000000030, 192.168.1.10000000029]
    我是master了:192.168.1.10000000029

  • 相关阅读:
    BZOJ2565:最长双回文串
    BZOJ2342:[SHOI2011]双倍回文
    Redis数据库基础操作
    Celery异步任务框架
    Django框架之缓存数据库
    drf 分页器组件
    drf jwt认证组件
    drf三大认证组件
    Django框架之RBAC+ContentType
    Django框架之admin管理后台
  • 原文地址:https://www.cnblogs.com/programlearning/p/6860881.html
Copyright © 2011-2022 走看看