Java學習筆記開源框架——dubbo啟動之註冊中心(Registry)
今天來分享下dubbo註冊中心的大致結構

服務註冊
對於服務提供方,它需要釋出服務,而且由於應用系統的複雜性,服務的數量、型別也不斷膨脹;對於服務消費方,它最關心如何獲取到它所需要的服務,而面對複雜的應用系統,需要管理大量的服務呼叫。而且,對於服務提供方和服務消費方來說,他們還有可能兼具這兩種角色,即既需要提供服務,有需要消費服務。通過將服務統一管理起來,可以有效地優化內部應用對服務釋出/使用的流程和管理。服務註冊中心可以通過特定協議來完成服務對外的統一
Registry: 服務註冊與發現的註冊中心。
RegistryFactory是註冊中心的入口,呼叫註冊中心方法的類是RegistryProtocol(下期會介紹)
先看下類圖關係

類圖可以看出
1:Dubbo提供的註冊中心有如下幾種型別可供選擇:
1:Multicast註冊中心
2:Zookeeper註冊中心
3:Redis註冊中心
4:Dubbo註冊中心
2:獲取註冊中心
通過呼叫RegistryFactory的Registry getRegistry(URL url)方法獲取註冊中心的資訊
Registry類圖如下

服務首先暴露在服務端,然後呼叫Registry的register方法在註冊中心(它是一個服務協調中心,dubbo以外的獨立服務端,dubbo提供了客戶端實現)註冊服務,然後使用者通過配置檔案中配置的service的url去subscribe(訂閱服務),Registry接收到訂閱訊息後會往url對應的的List中塞入當前NotifyListener,反之從這個list中移除listener就是取消訂閱。registry會呼叫據consumer的訂閱情況呼叫notify方法推送服務列表給Consumer。
注:
1:RegistryFactor在選擇註冊中心是通過SPI,預設是(dubbo)下圖

2:RegistryFactor中 getRegistry(URL url) 裡URL的資料來源是 的配置
詳解下zookeeper註冊中心
我們現在註冊中心 配置如下:
<dubbo:registry protocol=”zookeeper” address="127.0.0. 1:2181" />
通過spi呼叫的類和方法是
ZookeeperRegistryFactory
他裡面有個createRegistry方法 new ZookeeperRegistry(url, zookeeperTransporter);
我們先看下zookeeperTransporter,他是一個介面,CuratorZookeeperTransporter和 ZkclientZookeeperTransporter
通過spi可以看到他是呼叫zkclient,主要實現zk的連線。
預設採用zkClient, dubbo原始碼整合兩種zookeeper客戶端,除了zkClient還有一個是curator
zkclient=com.alibaba.dubbo.remoting.zookeeper.zkclient.ZkclientZookeeperTransporter
curator=com.alibaba.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter


1:ZookeeperRegistry建構函式,客戶端建立了對zookeeper的連線,並且添加了自動回覆連線的監聽器。
public ZookeeperRegistry(URL url, ZookeeperTransporter zookeeperTransporter) {
super(url);
if (url.isAnyHost()) {
throw new IllegalStateException("registry address == null");
}
String group = url.getParameter(Constants.GROUP_KEY, DEFAULT_ROOT);
if (! group.startsWith(Constants.PATH_SEPARATOR)) {
group = Constants.PATH_SEPARATOR + group;
}
this.root = group;
zkClient = zookeeperTransporter.connect(url);//這個是連線zk
zkClient.addStateListener(new StateListener() { //監聽器
public void stateChanged(int state) {
if (state == RECONNECTED) {
try {
recover();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
});
}
2.伺服器端建立url的節點,預設為臨時節點,客戶端與服務端斷開自動刪除(這個是zk的特性參考CreateMode列舉)
建立的節點可以是臨時和持久兩種
public void create(String path, boolean ephemeral) {
int i = path.lastIndexOf('/');
if (i > 0) {
create(path.substring(0, i), false);
}
if (ephemeral) {
createEphemeral(path);
} else {
createPersistent(path);
}
}
3:向伺服器端傳送註冊請求
protected void doRegister(URL url) {
try {
zkClient.create(toUrlPath(url), url.getParameter(Constants.DYNAMIC_KEY, true));
} catch (Throwable e) {
throw new RpcException("Failed to register " + url + " to zookeeper " + getUrl() + ", cause: " + e.getMessage(), e);
}
}
4:向伺服器端傳送取消註冊請求
protected void doUnregister(URL url) {
try {
zkClient.delete(toUrlPath(url));
} catch (Throwable e) {
throw new RpcException("Failed to unregister " + url + " to zookeeper " + getUrl() + ", cause: " + e.getMessage(), e);
}
}
註冊BUG問題:
之前我用帶有賬號和密碼的redis註冊中心發現是連線不上的,通過原始碼分析裡面並沒有注入賬號和密碼我們看程式碼
類名是:RedisRegistry

在new JedisPool的時候沒注入password和username
最後
如果你對技術提升很感興趣,可以加入我的Java進階之路來交流學習:878249276,裡面都是同行,有資源共享。歡迎一到五年的工程師加入,合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!