高級程序員知識學習(Dubbo相關知識)

Dubbo 是一款高性能、輕量級的開源 RPC 框架,提供服務自動註冊、自動發現等高效服務治理方案,。

RPC的原理及組成

https://img-blog.csdnimg.cn/20200128141852699.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly90aGlua3dvbi5ibG9nLmNzZG4ubmV0,size_16,color_FFFFFF,t_70

Provider:暴露服務的服務提供方

Consumer:調用遠程服務消費方

Registry:服務註冊與發現註冊中心

Monitor:監控中心和訪問調用統計

Container:服務運行容器

Dubbo 和 Spring Cloud 有什麼哪些區別?

Dubbo 底層是使用 Netty 這樣的 NIO 框架,是基於 TCP 協議傳輸的,配合以 Hession 序列化完成 RPC 通信。

Spring Cloud 是基於 Http 協議 Rest 接口調用遠程過程的通信,相對來說 Http 請求會有更大的報文,佔的帶寬也會更多。但是 REST 相比 RPC 更爲靈活,服務提供方和調用方的依賴只依靠一紙契約,不存在代碼級別的強依賴,這在強調快速演化的微服務環境下,顯得更爲合適,至於注重通信速度還是方便靈活性,具體情況具體考慮。

Dubbo 有哪些註冊中心?

    Multicast 註冊中心:Multicast 註冊中心不需要任何中心節點,只要廣播地址,就能進行服務註冊和發現,基於網絡中組播傳輸實現。

    Zookeeper 註冊中心:基於分佈式協調系統 Zookeeper 實現,採用 Zookeeper 的 watch 機制實現數據變更。

    Redis 註冊中心:基於 Redis 實現,採用 key/map 存儲,key 存儲服務名和類型,map 中 key 存儲服務 url,value 服務過期時間。基於 Redis 的發佈/訂閱模式通知數據變更。

Simple 註冊中心。

推薦使用 Zookeeper 作爲註冊中心

Dubbo 的註冊中心集羣掛掉,發佈者和訂閱者之間還能通信麼?

可以通訊。啓動 Dubbo 時,消費者會從 Zookeeper 拉取註冊的生產者的地址接口等數據,緩存在本地。每次調用時,按照本地存儲的地址進行調用。

Dubbo的服務和路由策略

Dubbo是一個分佈式服務框架,能避免單點故障和支持服務的橫向擴容。一個服務通常會部署多個實例。如何從多個服務 Provider 組成的集羣中挑選出一個進行調用,就涉及到一個負載均衡的策略

有一個Dubbo的用戶服務,在北京部署了10個,在上海部署了20個。一個杭州的服務消費方發起了一次調用,然後發生了以下的事情:

    根據配置的路由規則,如果杭州發起的調用,會路由到比較近的上海的20個 Provider。

    根據配置的隨機負載均衡策略,在20個 Provider 中隨機選擇了一個來調用,假設隨機到了第7個 Provider。

    結果調用第7個 Provider 失敗了。

    根據配置的Failover集羣容錯模式,重試其他服務器。

    重試了第13個 Provider,調用成功。

上面的第1,2,4步驟就分別對應了路由,負載均衡和集羣容錯。 Dubbo中,先通過路由,從多個 Provider 中按照路由規則,選出一個子集。再根據負載均衡從子集中選出一個 Provider 進行本次調用。如果調用失敗了,根據集羣容錯策略,進行重試或定時重發或快速失敗等。 可以看到Dubbo中的路由,負載均衡和集羣容錯發生在一次RPC調用的不同階段。最先是路由,然後是負載均衡,最後是集羣容錯。 本文檔只討論負載均衡,路由和集羣容錯在其他的文檔中進行說明。

Dubbo內置了4種負載均衡策略:

RandomLoadBalance:隨機負載均衡。隨機的選擇一個。是Dubbo的默認負載均衡策略。

RoundRobinLoadBalance:輪詢負載均衡。輪詢選擇一個。

LeastActiveLoadBalance:最少活躍調用數,相同活躍數的隨機。活躍數指調用前後計數差。使慢的 Provider 收到更少請求,因爲越慢的 Provider 的調用前後計數差會越大。

ConsistentHashLoadBalance:一致性哈希負載均衡。相同參數的請求總落在同一臺機器上使用一致性 Hash 算法,讓相同參數的請求總是發到同一 Provider。當某一臺 Provider 崩潰時,原本發往該 Provider 的請求,基於虛擬節點,平攤到其它 Provider,不會引起劇烈變動。Dubbo的4種負載均衡的實現,大多數情況下能滿足要求。有時候,因爲業務的需要,我們可能需要實現自己的負載均衡策略。

注意RPC的負載均衡實在client端實現的,而不是在zk實現的。

Dubbo SPI 和 Java SPI 區別?

JDK SPI:

JDK 標準的 SPI 會一次性加載所有的擴展實現,如果有的擴展很耗時,但也沒用上,很浪費資源。所以只希望加載某個的實現,就不現實了

DUBBO SPI:

1、對 Dubbo 進行擴展,不需要改動 Dubbo 的源碼

2、延遲加載,可以一次只加載自己想要加載的擴展實現。

3、增加了對擴展點 IOC 和 AOP 的支持,一個擴展點可以直接 setter 注入其

它擴展點。

4、Dubbo 的擴展機制能很好的支持第三方 IoC 容器,默認支持 Spring Bean

Dubbo的設計模式

Dubbo 用到哪些設計模式?

Dubbo 框架在初始化和通信過程中使用了多種設計模式,可靈活控制類加載、權限控制等功能。

工廠模式

Provider 在 export 服務時,會調用 ServiceConfig 的 export 方法。ServiceConfig中有個字段:

private static final Protocol protocol =

ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtensi

on();

Dubbo 裏有很多這種代碼。這也是一種工廠模式,只是實現類的獲取採用了 JDKSPI 的機制。這麼實現的優點是可擴展性強,想要擴展實現,只需要在 classpath下增加個文件就可以了,代碼零侵入。另外,像上面的 Adaptive 實現,可以做到調用時動態決定調用哪個實現,但是由於這種實現採用了動態代理,會造成代碼調試比較麻煩,需要分析出實際調用的實現類。

裝飾器模式

Dubbo 在啓動和調用階段都大量使用了裝飾器模式。以 Provider 提供的調用鏈爲例,具體的調用鏈代碼是在 ProtocolFilterWrapper 的 buildInvokerChain 完成的,具體是將註解中含有 group=provider 的 Filter 實現,按照 order 排序,最後的調用順序是:

EchoFilter -> ClassLoaderFilter -> GenericFilter -> ContextFilter ->

ExecuteLimitFilter -> TraceFilter -> TimeoutFilter -> MonitorFilter ->

ExceptionFilter

更確切地說,這裏是裝飾器和責任鏈模式的混合使用。例如,EchoFilter 的作用是判斷是否是回聲測試請求,是的話直接返回內容,這是一種責任鏈的體現。而像ClassLoaderFilter 則只是在主功能上添加了功能,更改當前線程的 ClassLoader,這是典型的裝飾器模式。

RPC的關鍵技術

1、動態代理

生成Client Stub(客戶端存根)和Server Stub(服務端存根)的時候需要用到Java動態代理技術,可以使用JDK提供的原生的動態代理機制,也可以使用開源的:CGLib代理,Javassist字節碼生成技術。

2、序列化和反序列化

在網絡中,所有的數據都將會被轉化爲字節進行傳送,所以爲了能夠使參數對象在網絡中進行傳輸,需要對這些參數進行序列化和反序列化操作。

    序列化:把對象轉換爲字節序列的過程稱爲對象的序列化,也就是編碼的過程。

    反序列化:把字節序列恢復爲對象的過程稱爲對象的反序列化,也就是解碼的過程。

目前比較高效的開源序列化框架:如Kryo、FastJson和Protobuf等。

3、NIO通信

出於併發性能的考慮,傳統的阻塞式 IO 顯然不太合適,因此我們需要異步的 IO,即 NIO。Java 提供了 NIO 的解決方案,Java 7 也提供了更優秀的 NIO.2 支持。可以選擇Netty或者MINA來解決NIO數據傳輸的問題。

4、服務註冊中心

可選:Redis、Zookeeper、Consul 、Etcd。一般使用ZooKeeper提供服務註冊與發現功能,解決單點故障以及分佈式部署的問題(註冊中心)。

Dubbo 使用的是什麼通信框架?

默認使用 Netty 作爲通訊框架。

Dubbo 支持哪些協議,它們的優缺點有哪些?

    Dubbo: 單一長連接和 NIO 異步通訊,適合大併發小數據量的服務調用,以及消費者遠大於提供者。傳輸協議 TCP,異步 Hessian 序列化。Dubbo推薦使用dubbo協議。

    RMI: 採用 JDK 標準的 RMI 協議實現,傳輸參數和返回參數對象需要實現 Serializable 接口,使用 Java 標準序列化機制,使用阻塞式短連接,傳輸數據包大小混合,消費者和提供者個數差不多,可傳文件,傳輸協議 TCP。 多個短連接 TCP 協議傳輸,同步傳輸,適用常規的遠程服務調用和 RMI 互操作。在依賴低版本的 Common-Collections 包,Java 序列化存在安全漏洞。

    WebService:基於 WebService 的遠程調用協議,集成 CXF 實現,提供和原生 WebService 的互操作。多個短連接,基於 HTTP 傳輸,同步傳輸,適用系統集成和跨語言調用。

    HTTP: 基於 Http 表單提交的遠程調用協議,使用 Spring 的 HttpInvoke 實現。多個短連接,傳輸協議 HTTP,傳入參數大小混合,提供者個數多於消費者,需要給應用程序和瀏覽器 JS 調用。

    Hessian:集成 Hessian 服務,基於 HTTP 通訊,採用 Servlet 暴露服務,Dubbo 內嵌 Jetty 作爲服務器時默認實現,提供與 Hession 服務互操作。多個短連接,同步 HTTP 傳輸,Hessian 序列化,傳入參數較大,提供者大於消費者,提供者壓力較大,可傳文件。

    Memcache:基於 Memcache實現的 RPC 協議。

    Redis:基於 Redis 實現的RPC協議。

Dubbo 支持分佈式事務嗎?

目前暫時不支持,可與通過 tcc-transaction 框架實現

介紹:tcc-transaction 是開源的 TCC 補償性分佈式事務框架

TCC-Transaction 通過 Dubbo 隱式傳參的功能,避免自己對業務代碼的入侵。

Dubbo 可以對結果進行緩存嗎?

爲了提高數據訪問的速度。Dubbo 提供了聲明式緩存,以減少用戶加緩存的工作量<dubbo:reference cache=“true” />

其實比普通的配置文件就多了一個標籤 cache=“true”

Dubbo 必須依賴的包有哪些?

Dubbo 必須依賴 JDK,其他爲可選。

Dubbo 支持哪些序列化方式?

默認使用 Hessian 序列化,還有 Duddo、FastJson、Java 自帶序列化。

Dubbo 在安全方面有哪些措施?

    Dubbo 通過 Token 令牌防止用戶繞過註冊中心直連,然後在註冊中心上管理授權。

    Dubbo 還提供服務黑白名單,來控制服務所允許的調用方。

服務調用是阻塞的嗎?

默認是阻塞的,可以異步調用,沒有返回值的可以這麼做。Dubbo 是基於 NIO 的非阻塞實現並行調用,客戶端不需要啓動多線程即可完成並行調用多個遠程服務,相對多線程開銷較小,異步調用會返回一個 Future 對象。

服務提供者能實現失效踢出是什麼原理?

服務失效踢出基於 zookeeper 的臨時節點原理。

同一個服務多個註冊的情況下可以直連某一個服務嗎?

可以點對點直連,修改配置即可,也可以通過 telnet 直接某個服務。

Dubbo 服務降級,失敗重試怎麼做?

可以通過 dubbo:reference 中設置 mock=“return null”。mock 的值也可以修改爲 true,然後再跟接口同一個路徑下實現一個 Mock 類,命名規則是 “接口名稱+Mock” 後綴。然後在 Mock 類裏實現自己的降級邏輯

Dubbo 使用過程中都遇到了些什麼問題?

在註冊中心找不到對應的服務,檢查 service 實現類是否添加了@service 註解無法連接到註冊中心,檢查配置文件中的對應的測試 ip 是否正確。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章