ZooKeeper實踐:(1)集羣管理

前言:java

       隨着業務的擴大,用戶的增多,訪問量的增長,單機模式已經不能支撐,從而出現了從單機模式->垂直應用模式->集羣模式,集羣模式誕生了,伴隨着一堆問題也油然而生,Master怎麼選舉,機器故障及時移除集羣,添加機器瞭如何及時的感應到,Zookeeper不只能維護當前的集羣服務狀態,還能及時的選出master,它們的實現方式都是在Zookeeper上面註冊一個EPHEMERAL目錄節點,在建立目錄的父目錄上面調用getChildren(String path,boolean watch)設置watch爲true,註冊watcher事件,因爲是臨時節點,當服務器出現問題形成session丟失,相對應的目錄節點隨之刪除,Children節點發生變化,就會調用前面註冊的watcher,使集羣內的每一個節點都獲得新的集羣信息。反之,新增節點也是這樣。apache

注:master選舉,不一樣之處是註冊一個EPHEMERAL_SEQUENTIAL 目錄節點,咱們能夠選擇最小編號爲master,實現了動態選擇master,避免master出現單點故障服務器

1、架構體系session

     

二:模擬代碼架構

      監控類: this

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;
	}
}

 模擬程序:spa

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();
	
	}

}

 運行結果:3d

節點變化了:[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.10000000029blog

相關文章
相關標籤/搜索