說(shuō)一下Dubbo的工作原理?
答案是肯定可以的,我將從下面幾點(diǎn)進(jìn)行說(shuō)明:
1.dubbo 的調(diào)用流程
2.Dubbo整體設(shè)計(jì)
3.從源碼上說(shuō)明注冊(cè)中心掛了還是可以繼續(xù)通信的
Dubbo 調(diào)用流程架構(gòu)圖
流程說(shuō)明:
1.Provider(提供者)綁定指定端口并啟動(dòng)服務(wù)
2.提供者連接注冊(cè)中心,并發(fā)本機(jī)IP、端口、應(yīng)用信息和提供服務(wù)信息發(fā)送至注冊(cè)中心存儲(chǔ)
3.Consumer(消費(fèi)者),連接注冊(cè)中心 ,并發(fā)送應(yīng)用信息、所求服務(wù)信息至注冊(cè)中心
4.注冊(cè)中心根據(jù) 消費(fèi) 者所求服務(wù)信息匹配對(duì)應(yīng)的提供者列表發(fā)送至Consumer 應(yīng)用緩存。
5.Consumer 在發(fā)起遠(yuǎn)程調(diào)用時(shí)基于緩存的消費(fèi)者列表?yè)衿湟话l(fā)起調(diào)用。
6.Provider 狀態(tài)變更會(huì)實(shí)時(shí)通知注冊(cè)中心、在由注冊(cè)中心實(shí)時(shí)推送至Consumer
這么設(shè)計(jì)的意義:
Consumer 與Provider 解偶,雙方都可以橫向增減節(jié)點(diǎn)數(shù)。注冊(cè)中心對(duì)本身可做對(duì)等集群,可動(dòng)態(tài)增減節(jié)點(diǎn),并且任意一臺(tái)宕掉后,將自動(dòng)切換到另一臺(tái)去中心化,雙方不直接依懶注冊(cè)中心,即使注冊(cè)中心全部宕機(jī)短時(shí)間內(nèi)也不會(huì)影響服務(wù)的調(diào)用服務(wù)提供者無(wú)狀態(tài),任意一臺(tái)宕掉后,不影響使用Dubbo 整體設(shè)計(jì)config** 配置層**:對(duì)外配置接口,以 ServiceConfig, ReferenceConfig 為中心,可以直接初始化配置類,也可以通過 spring 解析配置生成配置類proxy 服務(wù)代理層:服務(wù)接口透明代理,生成動(dòng)態(tài)代理 擴(kuò)展接口為 ProxyFactoryregistry 注冊(cè)中心層:封裝服務(wù)地址的注冊(cè)與發(fā)現(xiàn),以服務(wù) URL 為中心,擴(kuò)展接口為 RegistryFactory, Registry, RegistryServicecluster 路由層:封裝多個(gè)提供者的路由及負(fù)載均衡,并橋接注冊(cè)中心,以 Invoker 為中心,擴(kuò)展接口為 Cluster, Directory, Router, LoadBalancemonitor 監(jiān)控層:RPC 調(diào)用次數(shù)和調(diào)用時(shí)間監(jiān)控,以 Statistics 為中心,擴(kuò)展接口為 MonitorFactory, Monitor, MonitorServiceprotocol 遠(yuǎn)程調(diào)用層:封裝 RPC 調(diào)用,以 Invocation, Result 為中心,擴(kuò)展接口為 Protocol, Invoker, Exporterexchange 信息交換層:封裝請(qǐng)求響應(yīng)模式,同步轉(zhuǎn)異步,以 Request, Response 為中心,擴(kuò)展接口為 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServertransport 網(wǎng)絡(luò)傳輸層:抽象 mina 和 netty 為統(tǒng)一接口,以 Message 為中心,擴(kuò)展接口為 Channel, Transporter, Client, Server, Codecserialize 數(shù)據(jù)序列化層:可復(fù)用的一些工具,擴(kuò)展接口為 Serialization, ObjectInput, ObjectOutput, ThreadPool其協(xié)作流程如下:
從源碼上說(shuō)明注冊(cè)中心掛了還是可以繼續(xù)通信的首先要把消費(fèi)者注冊(cè)到Zookeeper注冊(cè)中心
然后使用RegistryDirectory 監(jiān)聽一下幾個(gè)目錄(會(huì)自動(dòng)觸發(fā)一次去獲取這些目錄上的當(dāng)前數(shù)據(jù))
當(dāng)前所引入的服務(wù)的動(dòng)態(tài)配置目錄:/dubbo/config/dubbo/org.apache.dubbo.demo.DemoService:1.1.1:g1.configurators
當(dāng)前所引入的服務(wù)的提供者目錄:/dubbo/org.apache.dubbo.demo.DemoService/providers當(dāng)前所引入的服務(wù)的老版本動(dòng)態(tài)配置目錄:/dubbo/org.apache.dubbo.demo.DemoService/configurators當(dāng)前所引入的服務(wù)的老版本路由器目錄:/dubbo/org.apache.dubbo.demo.DemoService/routers比如監(jiān)控providers 目錄:
當(dāng)有服務(wù)提供者注冊(cè),zookeeper會(huì)自動(dòng)推動(dòng)給訂閱的消費(fèi)者,然后轉(zhuǎn)換為invoker存儲(chǔ)到緩存中
我們?cè)诳凑{(diào)用時(shí)的代碼:
我們看到 FailoverClusterInvoker 的doInvoke方法
Invoker<T> invoker = select(loadbalance, invocation, copyInvokers, invoked);
此方法根據(jù)負(fù)載均衡器去緩存中獲取一個(gè)invoker,
上面的 copyInvokers 就是上面我們緩存進(jìn)去的 List<Invoker>
invokers = routerChain.route(getConsumerUrl(), invocation);
總結(jié)在我們系統(tǒng)啟動(dòng)時(shí),已經(jīng)緩存了注冊(cè)中心上的所有服務(wù),后續(xù)的注冊(cè)中心掛了只會(huì)影響到后續(xù)則注冊(cè),不會(huì)影響調(diào)用!