Dubbo常問面試題及答案
1、Dubbo是什麼?
Dubbo是阿里巴巴開源的基於 Java 的高性能、輕量級的 RPC 分佈式服務框架,可以和Spring無縫集成,並且提供了三大核心功能:面向接口的遠程方法調用、智能容錯和負載均衡、以及服務的自動註冊和發現。
2、爲什麼要用Dubbo?
3、Dubbo有哪些角色?
組件角色 | 說明 |
---|---|
Provider | 暴露服務的服務提供方 |
Consumer | 調用遠程服務的服務消費方 |
Registry | 服務註冊與發現的註冊中心 |
Monitor | 統計服務的調用次調和調用時間的監控中心 |
Container | 服務運行容器 |
4、Dubbo的各個角色的工作流程
- 服務容器 Container 負責啓動,加載,運行服務提供者。
- 服務提供者 Provider 在啓動時,向註冊中心註冊自己提供的服務。
- 服務消費者 Consumer 在啓動時,向註冊中心訂閱自己所需的服務。
- 註冊中心 Registry 返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
- 服務消費者 Consumer,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
- 服務消費者 Consumer 和提供者 Provider,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心 Monitor。
5、Dubbo和Spring cloud 有什麼不同?
- 通信方式不同
Dubbo 使用的是 RPC 通信,而 Spring Cloud 使用的是 HTTP RESTFul 方式。 - 組成部分不同
6、Dubbo有哪幾種集羣容錯方案,默認是哪種?
- Failover Cluster(默認)
失敗自動切換,當出現失敗,重試其它服務器。(缺省)通常用於讀操作,但重試會帶來更長延遲。 可通過retries="2"來設置重試次數(不含第一次)。
<dubbo:service retries="2" cluster="failover"/>
或:
<dubbo:reference retries="2" cluster="failover"/>
cluster="failover"可以不用寫,因爲默認就是failover
- Failfast Cluster
快速失敗,只發起一次調用,失敗立即報錯。通常用於非冪等性的寫操作,比如新增記錄。
<dubbo:service cluster="failfast" />
或:
<dubbo:reference cluster="failfast" />
cluster="failfast"和 把cluster="failover"、retries="0"是一樣的效果,retries="0"就是不重試
- Failsafe Cluster
失敗安全,出現異常時,直接忽略。通常用於寫入審計日誌等操作。
<dubbo:service cluster="failsafe" />
或:
<dubbo:reference cluster="failsafe" />
- Failback Cluster
失敗自動恢復,後臺記錄失敗請求,定時重發。通常用於消息通知操作。
<dubbo:service cluster="failback" />
或:
<dubbo:reference cluster="failback" />
- Forking Cluster
並行調用多個服務器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過forks="2"來設置最大並行數。
<dubbo:service cluster=“forking" forks="2"/>
或:
<dubbo:reference cluster=“forking" forks="2"/>
- Broadcast Cluster
廣播調用所有提供者,逐個調用,任意一臺報錯則報錯 [2]。通常用於通知所有提供者更新緩存或日誌等本地資源信息。
7、Dubbo有哪幾種負載均衡策略,默認是哪種?
8、當一個服務接口有多種實現時怎麼做?
當一個接口有多種實現時,可以用 group 屬性來分組,服務提供方和消費方都指定同一個 group 即可。
9、服務上線怎麼兼容舊版本?
可以用版本號(version)過渡,多個不同版本的服務註冊到註冊中心,版本號不同的服務相互間不引用。這個和服務分組的概念有一點類似。
10 、Dubbo 支持服務降級嗎?
以通過dubbo:reference 中設置 mock=“return null”。mock 的值也可以修改爲 true,然後再跟接口同一個路徑下實現一個 Mock 類,命名規則是 “接口名稱+Mock” 後綴。然後在 Mock 類裏實現自己的降級邏輯
11、Dubbo 如何優雅停機?
Dubbo 是通過 JDK 的 ShutdownHook 來完成優雅停機的,所以如果使用 kill -9 PID 等強制關閉指令,是不會執行優雅停機的,只有通過 kill PID 時,纔會執行。
12、Dubbo 和 Dubbox 之間的區別?
Dubbox 是繼 Dubbo 停止維護後,噹噹網基於 Dubbo 做的一個擴展項目,如加了服務可 Restful 調用,更新了開源組件等。
13、Dubbo 可以對結果進行緩存嗎?
爲了提高數據訪問的速度。Dubbo提供了聲明式緩存,以減少用戶加緩存的工作量
<dubbo:reference cache="true" />
其實比普通的配置文件就多了一個標籤 cache=“true”
14、服務上線怎麼兼容舊版本?
可以用版本號(version)過渡,多個不同版本的服務註冊到註冊中心,版本號不同的服務相互間不引用。這個和服務分組的概念有一點類似。
15、Dubbo必須依賴的包有哪些?
Dubbo 必須依賴 JDK,其他爲可選。
16、Dubbo telnet 命令能做什麼?
dubbo服務發佈之後,我們可以利用telnet命令進行調試、管理。 Dubbo2.0.5以上版本服務提供端口支持telnet命令
連接服務 telnet localhost 20880 //鍵入回車進入Dubbo命令模式。
查看服務列表
dubbo>ls
com.test.TestService
dubbo>ls com.test.TestService
create
delete
query
ls (list services and methods)
ls : 顯示服務列表。
ls -l : 顯示服務詳細信息列表。
ls XxxService:顯示服務的方法列表。
ls -l XxxService:顯示服務的方法詳細信息列表。
17、Dubbo 支持分佈式事務嗎?
目前暫時不支持,可與通過 tcc-transaction框架實現
介紹:tcc-transaction是開源的TCC補償性分佈式事務框架
Git地址:https://github.com/changmingxie/tcc-transaction
TCC-Transaction 通過 Dubbo 隱式傳參的功能,避免自己對業務代碼的入侵。
Dubbo 的整體架構設計有哪些分層?
接口服務層(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和Exporter
信息交換層(Exchange):封裝請求響應模式,同步轉異步。以 Request 和 Response 爲中心,擴展接口爲 Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer
網絡傳輸層(Transport):抽象 mina 和 netty 爲統一接口,以 Message 爲中心,擴展接口爲Channel、Transporter、Client、Server和Codec
數據序列化層(Serialize):可複用的一些工具,擴展接口爲Serialization、 ObjectInput、ObjectOutput和ThreadPool
默認使用的是什麼通信框架,還有別的選擇嗎?
默認也推薦使用netty框架,還有mina。
服務調用是阻塞的嗎?
默認是阻塞的,可以異步調用,沒有返回值的可以這麼做。
Dubbo 是基於 NIO 的非阻塞實現並行調用,客戶端不需要啓動多線程即可完成並行調用多個遠程服務,相對多線程開銷較小,異步調用會返回一個 Future 對象。
一般使用什麼註冊中心?還有別的選擇嗎?
推薦使用 Zookeeper 作爲註冊中心,還有 Redis、Multicast、Simple 註冊中心,但不推薦。
默認使用什麼序列化框架,你知道的還有哪些?
推薦使用Hessian序列化,還有Duddo、FastJson、Java自帶序列化。
服務提供者能實現失效踢出是什麼原理?
服務失效踢出基於zookeeper的臨時節點原理。
如何解決服務調用鏈過長的問題?
可以結合zipkin實現分佈式服務追蹤。
Dubbo 推薦用什麼協議?
dubbo://(推薦)
rmi://
hessian://
http://
webservice://
thrift://
memcached://
redis://
rest://
17、線程模型
需要通過不同的派發策略和不同的線程池配置的組合來應對不同的場景:
<dubbo:protocol name="dubbo" dispatcher="all" threadpool="fixed" threads="100" />
Dispatcher
- all 所有消息都派發到線程池,包括請求,響應,連接事件,斷開事件,心跳等。
- direct 所有消息都不派發到線程池,全部在 IO 線程上直接執行。
- message 只有請求響應消息派發到線程池,其它連接斷開事件,心跳等消息,直接在 IO 線程上執行。
- execution 只請求消息派發到線程池,不含響應,響應和其它連接斷開事件,心跳等消息,直接在 IO 線程上執行。
- connection 在 IO 線程上,將連接斷開事件放入隊列,有序逐個執行,其它消息派發到線程池。
ThreadPool
- fixed 固定大小線程池,啓動時建立線程,不關閉,一直持有。(缺省)
- cached 緩存線程池,空閒一分鐘自動刪除,需要時重建。
- limited 可伸縮線程池,但池中的線程數只會增長不會收縮。只增長不收縮的目的是爲了避免收縮時突然來了大流量引起的性能問題。
- eager 優先創建Worker線程池。在任務數量大於corePoolSize但是小
maximumPoolSize時,優先創建Worker來處理任務。當任務數量大
maximumPoolSize時,將任務放入阻塞隊列中。阻塞隊列充滿時拋
RejectedExecutionException。(相比於cached:cached在任務數量超過maximumPoolSize時直接拋出異常而不是將任務放入阻塞隊列)