一、引言
Zookeeper除了前面文章寫的強大功能以外,另外一個常見應用就是注冊中心了,比如Dubbo、SpringCloud等都可以使用ZK作為注冊中心,那么注冊中心為我們的系統做了什么工作呢?我們可以通過一張圖片來了解一下。
二、代碼實現
第1步:創建父節點
創建出來的父節點用於管理服務節點
第2步:編寫ZK服務端的代碼【這里只是以代碼的形式來了解ZK的原理,實際ZK已經幫我們做好了注冊中心的功能】
/** * 注冊中心測試類【服務端】 * * @author 有夢想的肥宅 * @date 2021/8/19 */ public class RegsterServerDemo { private CuratorFramework curatorFramework;//zk客戶端 private final String SERVICES_DEMO = "/serviceDemo"; /** * 使用main函數模擬注冊中心【ZK】的工作 */ public static void main(String[] args) throws Exception { RegsterServerDemo server = new RegsterServerDemo(); //1、獲取zk連接 server.getConnect(); //2、注冊服務器到zk集群 server.regist(args[0]);//由於這個是測試類,所以args[0]為從main函數入口傳入的主機ip地址【模擬上線一台機器的場景】 //3、模擬ZK持續運行【讓線程沉睡,否則執行完上面的代碼就結束了,無法看到注冊中心效果】 server.business(); } //1、獲取zk連接 private void getConnect() throws IOException { curatorFramework = ZookeeperClientUtil.getCuratorFramework(); } //2、注冊服務器到zk集群 private void regist(String hostname) throws Exception { //創建臨時順序節點 curatorFramework.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(SERVICES_DEMO + "/" + hostname, hostname.getBytes()); System.out.println(hostname + "上線了~"); } //3、模擬ZK持續運行【讓線程沉睡,否則執行完上面的代碼就結束了,無法看到注冊中心效果】 private void business() throws InterruptedException { Thread.sleep(Long.MAX_VALUE); } }
第3步:編寫ZK服務消費者的代碼【模擬服務消費者去感知服務器的上下線】
/** * 注冊中心測試類【客戶端/服務消費者】 * * @author 有夢想的肥宅 * @date 2021/8/19 */ public class RegsterClientDemo { private CuratorFramework curatorFramework;//zk客戶端 private final String SERVICES_DEMO = "/serviceDemo"; /** * 使用main函數模擬客戶端通過zk監聽服務上下線 */ public static void main(String[] args) throws Exception { RegsterClientDemo client = new RegsterClientDemo(); //1、獲取zk連接 client.getConnect(); //2、監聽/serviceDemo下面子節點的增加和刪除【獲取可用的服務器列表】 client.getServerList(); //3、模擬ZK持續運行【讓線程沉睡,否則執行完上面的代碼就結束了,無法看到注冊中心效果】 client.business(); } //1、獲取zk連接 private void getConnect() throws Exception { curatorFramework = ZookeeperClientUtil.getCuratorFramework(); } //2、獲取可用的服務器列表 private void getServerList() throws Exception { //服務器列表 ArrayList<String> servers = new ArrayList<>(); //獲取/serviceDemo下的子節點,並添加監聽 List<String> children = curatorFramework.getChildren().usingWatcher(new Watcher() { @Override public void process(WatchedEvent watchedEvent) { try { //當節點發生變動時,會去調用getServerList()方法獲取可用的服務器列表 getServerList(); } catch (Exception e) { e.printStackTrace(); } } }).forPath(SERVICES_DEMO); //循環獲取子節點的值【對應的主機地址】 for (String child : children) { byte[] data = curatorFramework.getData().forPath(SERVICES_DEMO + "/" + child); servers.add(new String(data)); } //打印 System.out.println(servers); } //3、模擬ZK持續運行【讓線程沉睡,否則執行完上面的代碼就結束了,無法看到注冊中心效果】 private void business() throws InterruptedException { Thread.sleep(Long.MAX_VALUE); } }
第4步:啟動服務消費者進行監聽,以命令行創建節點觀察服務消費者的變化
第5步:啟動服務端代碼,模擬服務器真實上線
在第4步我們已經驗證了,服務消費者可以正常監聽節點的變更,現在我們用代碼的方式來模擬服務器的上下線