1. 程式人生 > >dubbo源碼解析-zookeeper創建節點

dubbo源碼解析-zookeeper創建節點

分享 zook pub 基礎 一道 內容 可能 但是 chang

前言

在之前dubbo源碼解析-本地暴露中的前言部分提到了兩道高頻的面試題,其中一道dubbo中zookeeper做註冊中心,如果註冊中心集群都掛掉,那發布者和訂閱者還能通信嗎?在上周的dubbo源碼解析-zookeeper連接中已經講到,這周解析的是另一道,即服務提供者能實現失效踢出是根據什麽原理?

上周就有朋友問到我,為什麽我的源碼解析總是偏偏要和面試題掛上鉤呢?原因很簡單

1.dubbo源碼這麽多,試問你從哪裏做為切入點?也就是說該從哪裏看起?所以以面試題為切入點,你可以理解為我是在回答"怎麽看源碼"這個問題.

2.我們研發飛機大炮並不是為了侵略,有時候可能只是單純的想保護自己.

3.我的源碼解析雖然以面試題為基礎,但卻不以面試為目的.因為面試如果問到dubbo的問題,絕大多數都是官方文檔的內容,根本就沒到需要看源碼的程度.看源碼的最終目的是為了解決實際問題,後面我會以實際的問題為例子,實戰講一講看源碼我究竟解決了什麽網上搜不到,必須要看源碼才能弄清楚的問題.所以現在就可以大膽在簡書關註肥朝,已免後面錯過精彩內容.

插播面試題

  • 服務提供者能實現失效踢出是什麽原理(高頻題)

  • zookeeper的有哪些節點,他們有什麽區別?講一下應用場景

直入主題

同上周的zookeeper連接一樣,這周我們講的還是一行代碼,如下圖

技術分享圖片

那麽我們打上斷點開始

技術分享圖片 技術分享圖片

下面就要開始創建節點了

技術分享圖片 技術分享圖片 技術分享圖片 技術分享圖片

現在我們雖然看完源碼了,但是還是沒法回答面試題?那麽下面就要敲黑板劃重點了

技術分享圖片

敲黑板畫重點

zookeeper中節點是有生命周期的.具體的生命周期取決於節點的類型.節點主要分為持久節點(Persistent)臨時節點(Ephemeral),但是更詳細的話還可以加上時序節點(Sequential),創建節點中往往組合使用,因此也就是4種.

  • 持久節點
  • 持久順序節點
  • 臨時節點
  • 臨時順序節點

其實不要糾結於分為幾種,這就和語文的斷句一樣,你斷句的方法不同,斷出來的結果也不同.那麽我們主要講講持久節點

臨時節點的區別

持久節點

所謂持久節點,是指在節點創建後,就一直存在,直到有刪除操作來主動清除這個節點,也就是說不會因為創建該節點的客戶端會話失效而消失

臨時節點

臨時節點的生命周期和客戶端會話綁定,也就是說,如果客戶端會話失效,那麽這個節點就會自動被清除掉

應用場景

zookeeper常用的應用場景我在上周已經畫了思維導圖,這裏就不重復展示了.就拿分布式協調/通知來舉例(這個例子既是在回答第一個面試題,也是在回答第二個面試題).

在分布式系統中,我們常常需要知道某個機器是否可用,傳統的開發中,可以通過Ping某個主機來實現,Ping得通說明對方是可用的,相反是不可用的,ZK 中我們讓所有的機其都註冊一個臨時節點,我們判斷一個機器是否可用,我們只需要判斷這個節點在ZK中是否存在就可以了,不需要直接去連接需要檢查的機器,降低系統的復雜度

寫在最後

集群容錯後,服務發布的內容講得也差不多了.下周來和大家一起對服務發布做一個總結.期待下周繼續與你相遇.鑒於本人才疏學淺,不對的地方還望斧正,也歡迎關註我的簡書,名稱為肥朝




dubbo使用的 zkclient 會自動給 zookeeper發送心跳檢測的 18:29:10.363 [main-SendThread(114.67.228.245:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Got ping response for sessionid: 0x165add7ce0d000e after 9ms
18:29:20.363 [main-SendThread(114.67.228.245:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Got ping response for sessionid: 0x165add7ce0d000e after 9ms
18:29:30.366 [main-SendThread(114.67.228.245:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Got ping response for sessionid: 0x165add7ce0d000e after 9ms
18:29:40.369 [main-SendThread(114.67.228.245:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Got ping response for sessionid: 0x165add7ce0d000e after 11ms
18:29:50.366 [main-SendThread(114.67.228.245:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Got ping response for sessionid: 0x165add7ce0d000e after 8ms
18:30:00.369 [main-SendThread(114.67.228.245:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Got ping response for sessionid: 0x165add7ce0d000e after 9ms
18:30:10.370 [main-SendThread(114.67.228.245:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Got ping response for sessionid: 0x165add7ce0d000e after 9ms 測試發送心跳代碼 會自動打印出debug的日誌
package com.TestZookeeper;

import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;

public class ZookerProgram {
    //zookeeper連接地址
    private static final String CONNECT_ADR="XX.XX.XX.XX:2181";

    public static void main(String[]args)  throws Exception{
        ZkClient zkClient = new ZkClient(CONNECT_ADR,5000);
        String path="/qq";
   System.out.println("鏈接成功");
   zkClient.createEphemeral(path,"contentaaa");

        System.out.println("創建臨時節點成功");
      //  String msg=   zkClient.getChildren("/qq");

        zkClient.subscribeDataChanges(path, new IZkDataListener() {
            public void handleDataDeleted(String dataPath) throws Exception {
                System.out.println("Node " + dataPath + " deleted.");
            }
            public void handleDataChange(String dataPath, Object data) throws Exception {
                System.out.println("Node " + dataPath + " changed, new data: " + data);
            }
        });
      System.out.println("關閉前:"+zkClient.getCreationTime(path));
//       zkClient.close();
//        System.out.println("關閉後:"+zkClient.getCreationTime(path));
      // zkClient.writeData(path,"456");
     //   Thread.sleep(1000);
     //   zkClient.delete(path);
       Thread.sleep( Integer.MAX_VALUE );

    }
    }

dubbo源碼解析-zookeeper創建節點