一、整體架構設計分層
接口服務層(Service):該層與業務邏輯相關,根據provider和consumer的業務設計對應的接口和實現
配置層(Config):對外配置接口,以ServiceConfig和ReferenceConfig為中心
服務代理層(Proxy):服務接口透明代理,生成服務的客戶端Stub和Skeleton,以ServiceProxy為中心,擴展接口為ProxyFactory
服務注冊層(Registry):封裝服務地址的注冊和發現,以服務URL為中心,擴展接口為RegistryFactory、Registry、RegistryService
路由層(Cluster):封裝多個提供者的路由和負載均衡,并橋接注冊中心,以Invoker為中心,擴展接口為 Cluster、Directory、Router 和 LoadBlancce
監控層(Monitor):RPC調用次數和調用時間監控,以Statistics為中心,擴展接口為 MonitorFactory、Monitor 和 MonitorService
遠程調用層(Protocal):封裝RPC調用,以Invocation和Result為中心,擴展接口為 Protocal、Invoker 和 Exporte
信息交換層(Exchange):封裝請求響應模式,同步轉異步,以Request和Response為中心,擴展接口為Exchanger、ExchangeChannel、ExchangeClient 和 ExchangeServe
網絡傳輸層(Transport):抽象mina和netty為統一接口,以Message為中心,擴展接口為Channel、Transport、Client、Server和Codec
數據序列化層(Serialize):可復用的一些工具,擴展接口為 Serialization、ObjectInput、ObjectOutput 和 ThreadPoo
二、默認使用Netty框架,還有mina
三、服務調用阻塞
Dubbo 是基于 NIO 的非阻塞實現并行調用,客戶端不需要啟動多線程即可完成
并行調用多個遠程服務,相對多線程開銷較小,異步調用會返回一個 Future 對
象。
四、核心模塊
dubbo:service 服務配置
dubbo:reference 引用配置
dubbo:protocol 協議配置
dubbo:application 應用配置
dubbo:module 模塊配置
dubbo:registry 注冊中心配置
dubbo:monitor 監控中心配置
dubbo:provider 提供方配置
dubbo:consumer 消費方配置
dubbo:method 方法配置
dubbo:argument 參數配置
五、集群容錯方案
Failover Cluster 失敗自動切換,自動重試其它服務器(默認)
Failfast Cluster 快速失敗,立即報錯,只發起一次調用
Failsafe Cluster 失敗安全,出現異常時,直接忽略
Failback Cluster 失敗自動恢復,記錄失敗請求,定時重發
Forking Cluster 并行調用多個服務器,只要一個成功即返回
Broadcast Cluster 廣播逐個調用所有提供者,任意一個報錯則報錯
六、Dubbo服務降級
通過 dubbo:reference 中設置 mock=“return null”。mock 的值也可以修
改為 true,然后再跟接口同一個路徑下實現一個 Mock 類,命名規則是 “接口
名稱+Mock” 后綴。然后在 Mock 類里實現自己的降級邏輯
七、Dubbo Monitor實現原理
Consumer 端在發起調用之前會先走 filter 鏈;provider 端在接收到請求時也是
先走 filter 鏈,然后才進行真正的業務邏輯處理。默認情況下,在 consumer 和 provider 的 filter 鏈中都會有 Monitorfilter。
1、MonitorFilter 向 DubboMonitor 發送數據
2、DubboMonitor 將數據進行聚合后(默認聚合 1min 中的統計數據)暫存到
ConcurrentMap<Statistics, AtomicReference> statisticsMap,然后使用一個
含有 3 個線程(線程名字:DubboMonitorSendTimer)的線程池每隔 1min 鐘,
調用 SimpleMonitorService 遍歷發送 statisticsMap 中的統計數據,每發送完畢
一個,就重置當前的 Statistics 的 AtomicReference
3、SimpleMonitorService 將這些聚合數據塞入 BlockingQueue queue 中(隊
列大寫為 100000)
4、SimpleMonitorService 使用一個后臺線程(線程名為:
DubboMonitorAsyncWriteLogThread)將 queue 中的數據寫入文件(該線程以
死循環的形式來寫)
5、SimpleMonitorService 還會使用一個含有 1 個線程(線程名字:
DubboMonitorTimer)的線程池每隔 5min 鐘,將文件中的統計數據畫成圖表
八、設計模式
工廠模式:Provider 在 export 服務時,會調用 ServiceConfig 的 export 方法。ServiceConfig
中有個字段:
裝飾器模式:Dubbo 在啟動和調用階段都大量使用了裝飾器模式。以 Provider 提供的調用鏈為例,具體的調用鏈代碼是在 ProtocolFilterWrapper 的 buildInvokerChain 完成的,具體是將注解中含有group=provider 的 Filter 實現,按照 order 排序,最后的調用順序是,更確切地說,這里是裝飾器和責任鏈模式的混合使用。例如,EchoFilter 的作用是判斷是否是回聲測試請求,是的話直接返回內容,這是一種責任鏈的體現。而像ClassLoaderFilter 則只是在主功能上添加了功能,更改當前線程的ClassLoader,這是典型的裝飾器模式。
觀察者模式:Dubbo 的 Provider 啟動時,需要與注冊中心交互,先注冊自己的服務,再訂閱自己的服務,訂閱時,采用了觀察者模式,開啟一個 listener。注冊中心會每 5 秒定時檢查是否有服務更新,如果有更新,向該服務的提供者發送一個 notify 消息,provider 接受到 notify 消息后,即運行 NotifyListener 的 notify 方法,執行監聽器方法。
動態代理模式:Dubbo 擴展 JDK SPI 的類 ExtensionLoader 的 Adaptive 實現是典型的動態代理實現。Dubbo 需要靈活地控制實現類,即在調用階段動態地根據參數決定調用哪個實現類,所以采用先生成代理類的方法,能夠做到靈活的調用。生成代理類的代碼是 ExtensionLoader 的 createAdaptiveExtensionClassCode 方法。代理類的主要邏輯是,獲取 URL 參數中指定參數的值作為獲取實現類的 key。
九、Dubbo配置文件加載到Spring中
Spring 容器在啟動的時候,會讀取到 Spring 默認的一些 schema 以及 Dubbo 自定義的 schema,每個 schema 都會對應一個自己的 NamespaceHandler,NamespaceHandler 里面通過 BeanDefinitionParser 來解析配置信息并轉化為需要加載的 bean 對象。
十、Dubbo SPI和Java SPI
Java SPI
JDK 標準的 SPI 會一次性加載所有的擴展實現,如果有的擴展吃實話很耗時,但也沒用上,很浪費資源。
DUBBO SPI
1,對 Dubbo 進行擴展,不需要改動 Dubbo 的源碼
2,延遲加載,可以一次只加載自己想要加載的擴展實現。
3,增加了對擴展點 IOC 和 AOP 的支持,一個擴展點可以直接 setter 注入其它擴展點。
4,Dubbo 的擴展機制能很好的支持第三方 IoC 容器,默認支持 Spring Bean。