37 個 Dubbo 連環炮,能扛住幾個?最後幾個還是有點難度

今天,我給你帶來了 Dubbo 的 37 連環炮,咱們不耍流氓只給面試題不給參考答案,所以,老田也給大家整理參考答案以及 Dubbo 核心知識點的梳理。

本文結合自身對 Dubbo 的理解、網上的資源以及官網上的資料,給大家整理了 Dubbo 連環炮。

如果讓黃忠搞 37 個連環炮是什麼概念?

37 個 Dubbo 連環炮如下:

1、什麼是 Dubbo?

2、爲什麼要用 Dubbo?

3、Dubbo 能做什麼?

4、Dubbo 的整體架構設計有哪些分層?

5、默認使用的是什麼通信框架,還有別的選擇嗎?

6、一般使用什麼註冊中心?還有別的選擇嗎?

7、默認使用什麼序列化框架,你知道的還有哪些?

8、說說 Hessian 序列化

9、說說 Dubbo 支持哪些協議,每種協議的應用場景和優缺點

10、註冊中心掛了,consumer 還能不能調用 provider?

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

12、服務上線怎麼不影響舊版本?

13、如何解決服務調用鏈過長的問題?

14、說說核心的配置有哪些?

15、Dubbo 推薦用什麼協議?

16、Dubbo 負載均衡策略?

17、Dubbo 有哪些容錯策略?

18、Dubbo 動態代理策略有哪些?

19、服務提供者沒掛,但在註冊中心裏看不到,怎麼辦?

20、Dubbo 內置了哪幾種服務容器?

21、Dubbo 啓動時如果依賴的服務不可用會怎樣?

22、Dubbo 如何優雅停機?

23、說說 Dubbo 服務暴露的過程

24、說說 Dubbo 服務引用的流程

25、說說 Dubbo 的優先級配置

26、說說一次 Dubbo 服務請求流程?

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

28、Dubbo 配置文件是如何加載到 Spring 中的?

29、Dubbo 使用過程中都遇到了些什麼問題,如何解決的?

30、Dubbo 和 Dubbox 之間的區別?

31、畫一畫服務註冊與發現的流程圖?

32、Dubbo SPI 和 Java SPI 區別?

33、Dubbo 支持分佈式事務嗎?

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

35、Dubbo 和 Spring Cloud 的區別?

36、如何自己設計一個類似 Dubbo 的 RPC 框架?

37、Dubbo 用到哪些設計模式?

....

Dubbo 核心知識

這裏整理一份關於 Dubbo 核心知識的思維導圖:

接再來,我們正式開始 Dubbo 的 36 連環炮:

1、什麼是 Dubbo?

Dubbo 是基於 Java 的高性能輕量級的 RPC 分佈式服務框架,有阿里巴巴團隊開發,現已成爲 Apache 基金會孵化項目。

2、爲什麼要用 Dubbo?

Dubbo 的誕生和 SOA 分佈式架構的流行有着莫大的關係。SOA 面向服務的架構(Service Oriented Architecture),也就是把工程按照業務邏輯拆分成服務層、表現層兩個工程。服務層中包含業務邏輯,只需要對外提供服務即可。表現層只需要處理和頁面的交互,業務邏輯都是調用服務層的服務來實現。

SOA 架構中有兩個主要角色:

如果你要開發分佈式程序,你也可以直接基於 HTTP 接口進行通信,但是爲什麼要用 Dubbo 呢?

3、Dubbo 能做什麼?

透明化的遠程方法調用,就像調用本地方法一樣調用遠程方法。

只需簡單配置,沒有任何 API 侵入。

軟負載均衡及容錯機制,可在內網替代 F5 等硬件負載均衡器,降低成本,減少單點。

服務自動註冊與發現,不再需要寫死服務提供方地址,註冊中心基於接口名查詢服務提供者的 IP 地址,並且能夠平滑添加或刪除服務提供者。

4、Dubbo 的整體架構設計有哪些分層?

Dubbo 的整體設計分 10 層:

第一層:service 層,接口層,給服務提供者和消費者來實現的(留給開發人員來實現);

第二層:config 層,配置層,主要是對 Dubbo 進行各種配置的,Dubbo 相關配置;

第三層:proxy 層,服務代理層,透明生成客戶端的 stub 和服務單的 skeleton,調用的是接

口,實現類沒有,所以得生成代理,代理之間再進行網絡通訊、負責均衡等;

第四層:registry 層,服務註冊層,負責服務的註冊與發現;

第五層:cluster 層,集羣層,封裝多個服務提供者的路由以及負載均衡,將多個實例組合成一 個服務;

第六層:monitor 層,監控層,對 rpc 接口的調用次數和調用時間進行監控;

第七層:protocol 層,遠程調用層,封裝 rpc 調用;

第八層:exchange 層,信息交換層,封裝請求響應模式,同步轉異步;

第九層:transport 層,網絡傳輸層,抽象 mina 和 netty 爲統一接口;

第十層:serialize 層,數據序列化層。

這是個很坑爹的面試題,但是很多面試官又喜歡問,你真的要背麼?你能背那還是不錯的,我建議 不要背,你就想想 Dubbo 服務調用過程中應該會涉及到哪些技術,把這些技術串起來就 OK 了。

5、默認使用的是什麼通信框架,還有別的選擇嗎?

Dubbo 默認使用 Netty 框架,也是推薦的選擇,另外內容還集成有 Mina、Grizzly。

6、一般使用什麼註冊中心?還有別的選擇嗎?

Dubbo 官方推薦使用 Zookeeper 作爲註冊中心,還有 Redis、Multicast、Simple 也可以作爲 Dubbo 的註冊中心。

7、默認使用什麼序列化框架,你知道的還有哪些?

默認使用 Hessian 序列化,還有 Duddo、FastJson、Java 自帶序列化。hessian 是一個採用二進制格式傳輸的服務框架,相對傳統 soap web service,更輕量,更快速。

8、說說 Hessian 序列化

hessian 的協議本身並不複雜,在此不再贅言;所謂協議 (protocol) 就是約束數據的格式,client 按照協議將請求信息序列化成字節序列發送給 server 端,server 端根據協議,將數據反序列化成 “對象”,然後執行指定的方法,並將方法的返回值再次按照協議序列化成字節流,響應給 client,client 按照協議將字節流反序列化成” 對象”。

9、說說 Dubbo 支持哪些協議,每種協議的應用場景和優缺點

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

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:基於 memcached 實現的 RPC 協議 redis:基於 redis 實現的 RPC 協議

10、註冊中心掛了,consumer 還能不能調用 provider?

可以。因爲剛開始初始化的時候,consumer 會將需要的所有提供者的地址等信息拉取到本地緩 存,所以註冊中心掛了可以繼續通信。但是 provider 掛了,那就沒法調用了。

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

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

Zookeeper 中節點是有生命週期的,具體的生命週期取決於節點的類型,節點主要分爲持久節點 (Persistent) 和臨時節點(Ephemeral) 。

12、服務上線怎麼不影響舊版本?

通過 Dubbo 配置中的 version 版本來控制,設置多個版本即可。

比如:老版本 version=1.0.0,那麼新版本可以改成 version=1.0.1。

13、如何解決服務調用鏈過長的問題?

Dubbo 可以使用 PinpointApache Skywalking(Incubator)實現分佈式服務追蹤。也可以結合 zipkin 實現分佈式服務追蹤。

14、說說核心的配置有哪些?

最後兩個不回答,也是沒問題的,但是得熟悉,面試官如果提示性的追問,這樣就可以聯繫到方法和參數。

15、Dubbo 推薦用什麼協議?

Dubbo 支持 dubbo、rmi、hessian、http、webservice、thrift、redis 等多種協議,但是 Dubbo 官網是推薦我們使用 dubbo 協議的。

16、Dubbo 負載均衡策略?

17、Dubbo 有哪些容錯策略?

failover cluster 模式

provider 宕機重試以後,請求會分到其他的 provider 上,默認兩次,可以手動設置重試次數,建議把寫操作重試次數設置成 0。

failback 模式

失敗自動恢復會在調用失敗後,返回一個空結果給服務消費者。並通過定時任務對失敗的調用進行重試,適合執行消息通知等操作。

failfast cluster 模式

快速失敗只會進行一次調用,失敗後立即拋出異常。適用於冪等操作、寫操作,類似於 failover cluster 模式中重試次數設置爲 0 的情況。

failsafe cluster 模式

失敗安全是指,當調用過程中出現異常時,僅會打印異常,而不會拋出異常。適用於寫入審計日誌等操作。

forking cluster 模式

並行調用多個服務器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過  forks="2" 來設置最大並行數。

broadcacst cluster 模式

廣播調用所有提供者,逐個調用,任意一臺報錯則報錯。通常用於通知所有提供者更新緩存或日誌等本地資源信息。

18、Dubbo 動態代理策略有哪些?

默認使用 javassist 動態字節碼生成,創建代理類,但是可以通過 SPI 擴展機制配置自己的動態代理策略。

19、服務提供者沒掛,但在註冊中心裏看不到,怎麼辦?

首先,確認服務提供者是否連接了正確的註冊中心,不只是檢查配置中的註冊中心地址,而且要檢查實際的網絡連接。

其次,看服務提供者是否非常繁忙,比如壓力測試,以至於沒有 CPU 片段向註冊中心發送心跳,這種情況減小壓力將自動恢復。

20、Dubbo 內置了哪幾種服務容器?

Dubbo 內置服務容器有三種:

Dubbo 的服務容器只是一個簡單的 Main 方法,並加載一個簡單的 Spring 容器,用於暴露服務。

21、Dubbo 啓動時如果依賴的服務不可用會怎樣?

Dubbo 缺省會在啓動時檢查依賴的服務是否可用,不可用時會拋出異常,阻止 Spring 初始化完成,默認 check="true",可以通過 check="false" 關閉檢查。

22、Dubbo 如何優雅停機?

Dubbo 是通過 JDK 的 ShutdownHook 來完成優雅停機的,所以如果使用 kill -9 PID 等強制關閉指令,是不會執行優雅停機的,只有通過 kill PID 時,纔會執行。

23、說說 Dubbo 服務暴露的過程

服務暴露會從Spring ioc容器刷新完成之後開始進行暴露。正式暴露前會將需要暴露的服務組裝成 URL 對象,該對象存儲了服務的 ip、端口號、全路徑名、parameters 參數(路由、分組、版本、超時時間、應用名等配置信息)等配置信息。

通過proxyFactory.getInvoker方法,並利用javassist來進行動態代理,將服務暴露接口封裝成 invoker 對象。然後開始正式暴露服務。

首先會將該invoker對象封裝成export對象放入到exportedMap中供之後的遠程調用查找。

然後會啓動註冊中心,將提供者信息註冊到註冊中心

最後對configurations節點進行訂閱。

以上就是服務暴露的總體流程。

24、說說 Dubbo 服務引用的流程

服務引用的時機有兩種,一種是餓漢式即加載完畢就會引入,另一種是懶漢式即只有當這個服務被注入到其他類中時啓動引入流程,默認是懶漢式。

服務引用首先會根據需要引入的配置信息組裝成 url 對象,並根據提供者的協議進入 Dubbo 協議的引入即XXXProtocol.refer。然後獲取註冊中心,如果註冊中心不存在會初始化註冊中心。接下來會向註冊中心註冊消費者信息,並且訂閱提供者、配置、路由等節點。

最後通過 Cluster.join 來包裝invoker,默認是failoverCluster,最終通過proxyFactory.getProxy返回代理類,代理類中包含了NettyClient來進行遠程通信。

25、說說 Dubbo 的優先級配置

配置優先級別 1. 以timeout爲例,顯示了配置的查找順序,其他 retries,loadbalance 等類似。

  1. 建議由服務提供方設置超時,因爲一個方法需要執行多長時間,服務提供方更清楚,如果一個消 費方同時引用多個服務,就不需要關心每個服務的超時設置。

26、說說一次 Dubbo 服務請求流程?

基本工作流程:

上圖中角色說明:

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

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

28、Dubbo 配置文件是如何加載到 Spring 中的?

Dubbo 採用全 Spring 配置方式,透明化接入應用,對應用沒有任何 API 侵入,只需用 Spring 加載 Dubbo 的配置即可。

Spring 容器在啓動的時候,會讀取到 Spring 默認的一些 schema 以及 Dubbo 自定義的 schema,每個 schema 都會對應一個自己的 NamespaceHandler,NamespaceHandler 裏面通過 BeanDefinitionParser 來解析配置信息並轉化爲需要加載的 bean 對象

29、Dubbo 使用過程中都遇到了些什麼問題,如何解決的?

下面羅列了七個問題,能說出三五個即可:

  1. 同時配置了 XMLproperties 文件,則 properties中的配置無效

只有 XML 沒有配置時,properties 才生效。

  1. dubbo 缺省會在啓動時檢查依賴是否可用,不可用就拋出異常,阻止 Spring 初始化完成,check 屬性默認爲 true。

測試時有些服務不關心或者出現了循環依賴,將 check 設置爲 false

  1. 爲了方便開發測試,線下有一個所有服務可用的註冊中心,這時,如果有一個正在開發中的服務提供者註冊,可能會影響消費者不能正常運行。

解決:讓服務提供者開發方,只訂閱服務,而不註冊正在開發的服務,通過直連測試正在開發的服務。設置 dubbo:registry標籤的 register 屬性爲 false。

  1. spring 2.x 初始化死鎖問題。

在 spring 解析到 dubbo:service 時,就已經向外暴露了服務,而 spring 還在接着初始化其他 bean,如果這時有請求進來,並且服務的實現類裏有調用 applicationContext.getBean() 的用法。getBean 線程和 spring 初始化線程的鎖的順序不一樣,導致了線程死鎖,不能提供服務,啓動不了。

解決:不要在服務的實現類中使用 applicationContext.getBean()``; 如果不想依賴配置順序,可以將dubbo:provider ` 的 deplay 屬性設置爲 - 1,使 dubbo 在容器初始化完成後再暴露服務。

  1. 服務註冊不上

檢查 dubbo 的 jar 包有沒有在 classpath 中,以及有沒有重複的 jar 包

檢查暴露服務的 Spring 配置有沒有加載

在服務提供者機器上測試與註冊中心的網絡是否通

  1. 出現 RpcException: No provider available for remote service 異常

表示沒有可用的服務提供者,

a. 檢查連接的註冊中心是否正確

b. 到註冊中心查看相應的服務提供者是否存在

c. 檢查服務提供者是否正常運行

  1. 出現” 消息發送失敗” 異常

通常是接口方法的傳入傳出參數未實現 Serializable 接口。

30、Dubbo 和 Dubbox 之間的區別?

Dubbox 是噹噹網基於 dubbo 上做了一些擴展,如加了服務可 restful 調用,更新了開源組件等。

31、畫一畫服務註冊與發現的流程圖?

這個可以參考官網給的圖來畫:

32、Dubbo SPI 和 Java SPI 區別?

JDK SPI

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

DUBBO SPI

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

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

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

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

33、Dubbo 支持分佈式事務嗎?

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

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

Git 地址:https://github.com/changmingxie/tcc-transaction

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

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

爲了提高數據訪問的速度

Dubbo 提供了聲明式緩存,以減少用戶加緩存的工作量

<dubbo:reference cache="true"

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

35、Dubbo 和 Spring Cloud 的區別?

根據微服務架構在各方面的要素,看看 Spring Cloud 和 Dubbo 都提供了哪些支持 。

dubbo 的優勢

SpringCloud 優勢

兩者相比較 1、Dubbo 由於是二進制的傳輸,佔用帶寬會更少 2、Spring Cloud 是 http 協議傳輸,帶寬會比較多,同時使用 http 協議一般會使用 JSON 報文,消耗 會更大 3、Dubbo 的開發難度較大,原因是 dubbo 的 jar 包依賴問題很多大型工程無法解決 4、Spring Cloud 的接口協議約定比較自由且鬆散,需要有強有力的行政措施來限制接口無序升級 5、dubbo 的註冊中心可以選擇 zk,redis 等多種,springcloud 的註冊中心只能用 eureka 或者自研

35、如何自己設計一個類似 Dubbo 的 RPC 框架?

遇到這類問題,起碼從你瞭解的類似框架的原理入手,自己說說參照 dubbo 的原理,你來設計一下,舉個例子,dubbo 不是有那麼多分層麼?而且每個分層是幹啥的,你大概是不是知道?那就按照這個思路大致說一下吧,起碼你不能懵逼,要比那些上來就懵,啥也說不出來的人要好一些。

舉個栗子,我給大家說個最簡單的回答思路:

這就是一個最最基本的 rpc 框架的思路,先不說你有多牛逼的技術功底,哪怕這個最簡單的思路你先給出來行不行?get 到了嗎?

37、Dubbo 用到哪些設計模式?

裝飾器模式:爲什麼生產者和消費者都要轉換爲 Invoker 而不是不直接調用呢?我認爲 Invoker 正是 Dubbo 設計精彩之處:真實調用都轉換爲 Invoker,Dubbo 就可以通過裝飾器模式增強 Invoker 功能。

責任鏈模式:EchoFilter -> ClassLoaderFilter -> GenericFilter -> ContextFilter -> ,EchoFilter 的作用是判斷是否是回聲測試請求,是的話直接返回內容,這是一種責任鏈的體現。ClassLoaderFilter 則只是在主功能上添加了功能,更改當前線程的 ClassLoader,這是典型的裝飾器模式。

觀察者模式:Dubbo 的 Provider 啓動時,需要與註冊中心交互,先註冊自己的服務,再訂閱自己的服務,訂閱時,採用了觀察者模式,開啓一個 listener。註冊中心會每 5 秒定時檢查是否有服務更新,如果有更新,向該服務的提供者發送一個 notify 消息,provider 接受到 notify 消息後,即運行 NotifyListener 的 notify 方法,執行監聽器方法。

動態代理模式:Dubbo 擴展 JDK SPI 的類 ExtensionLoader 的 Adaptive 實現是典型的動態代理實現。Dubbo 需要靈活地控制實現類,即在調用階段動態地根據參數決定調用哪個實現類,所以採用先生成代理類的方法,能夠做到靈活的調用。生成代理類的代碼是 ExtensionLoader 的 createAdaptiveExtensionClassCode 方法。代理類的主要邏輯是,獲取 URL 參數中指定參數的值作爲獲取實現類的 key。

適配器模式:爲了讓用戶根據自己的需求選擇日誌組件,Dubbo 自定義了自己的 Logger 接口,併爲常見的日誌組件(包括 jcl, jdk, log4j, slf4j)提供相應的適配器。並且利用簡單工廠模式提供一個 LoggerFactory,客戶可以創建抽象的 Dubbo 自定義 Logger,而無需關心實際使用的日誌組件類型。在 LoggerFactory 初始化時,客戶通過設置系統變量的方式選擇自己所用的日誌組件,這樣提供了很大的靈活性。

總結

其實,原本沒打算搞 Dubbo 連環炮,但是有朋友私下催我趕緊發。爲什麼沒打算寫呢?因爲 Dubbo 的文檔是用中文寫的,也是咱們國人寫的,所以我覺得看文檔就已經夠了。

但是,話又說回來,很多朋友都只是用過 Dubbo,或許還沒有對其進行深入的瞭解學習,但爲了應付面試,又覺得這個連環炮存在的意義在哪裏了。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/QQlf1XU-iCAVxeVbvIbvhg