1爽冕、為什么要用 Dubbo溅呢?
隨著服務(wù)化的進(jìn)一步發(fā)展杖狼,服務(wù)越來越多炼蛤,服務(wù)之間的調(diào)用和依賴關(guān)系也越來越復(fù)雜,誕生了面向服務(wù) 的架構(gòu)體系(SOA)蝶涩,也因此衍生出了一系列相應(yīng)的技術(shù)理朋,如對服務(wù)提供、服務(wù)調(diào)用绿聘、連接處理暗挑、通信協(xié) 議、序列化方式斜友、服務(wù)發(fā)現(xiàn)炸裆、服務(wù)路由、日志輸出等行為進(jìn)行封裝的服務(wù)框架鲜屏。就這樣為分布式系統(tǒng)的 服務(wù)治理框架就出現(xiàn)了烹看,Dubbo 也就這樣產(chǎn)生了国拇。
2、Dubbo 的整體架構(gòu)設(shè)計有哪些分層?
接口服務(wù)層(Service):該層與業(yè)務(wù)邏輯相關(guān)惯殊,根據(jù) provider 和 consumer 的業(yè)務(wù)設(shè)計對應(yīng)的接口和 實(shí)現(xiàn)
配置層(Con?g):對外配置接口酱吝,以 ServiceCon?g 和 ReferenceCon?g 為中心
服務(wù)代理層(Proxy):服務(wù)接口透明代理,生成服務(wù)的客戶端 Stub 和 服務(wù)端的 Skeleton土思,以 ServiceProxy 為中心务热,擴(kuò)展接口為 ProxyFactory
服務(wù)注冊層(Registry):封裝服務(wù)地址的注冊和發(fā)現(xiàn),以服務(wù) URL 為中心己儒,擴(kuò)展接口為 RegistryFactory崎岂、Registry、RegistryService
路由層(Cluster):封裝多個提供者的路由和負(fù)載均衡闪湾,并橋接注冊中心冲甘,以Invoker 為中心,擴(kuò)展接 口為 Cluster途样、Directory江醇、Router 和 LoadBlancce
監(jiān)控層(Monitor):RPC 調(diào)用次數(shù)和調(diào)用時間監(jiān)控,以 Statistics 為中心何暇,擴(kuò)展接口為 MonitorFactory陶夜、Monitor 和 MonitorService
遠(yuǎn)程調(diào)用層(Protocal):封裝 RPC 調(diào)用,以 Invocation 和 Result 為中心裆站,擴(kuò)展接口為 Protocal律适、 Invoker 和 Exporter
信息交換層(Exchange):封裝請求響應(yīng)模式,同步轉(zhuǎn)異步遏插。以 Request 和Response 為中心,擴(kuò)展 接口為 Exchanger纠修、ExchangeChannel胳嘲、ExchangeClient 和 ExchangeServer
網(wǎng)絡(luò)傳輸層(Transport):抽象 mina 和 netty 為統(tǒng)一接口,以 Message 為中心扣草,擴(kuò)展接口為 Channel了牛、Transporter、Client辰妙、Server 和 Codec
數(shù)據(jù)序列化層(Serialize):可復(fù)用的一些工具鹰祸,擴(kuò)展接口為 Serialization、ObjectInput密浑、 ObjectOutput 和 ThreadPool
3蛙婴、默認(rèn)使用的是什么通信框架,還有別的選擇嗎?
默認(rèn)也推薦使用 netty 框架尔破,還有 mina
4街图、服務(wù)調(diào)用是阻塞的嗎浇衬?
默認(rèn)是阻塞的,可以異步調(diào)用餐济,沒有返回值的可以這么做耘擂。
Dubbo 是基于 NIO 的非阻塞實(shí)現(xiàn)并行調(diào)用,客戶端不需要啟動多線程即可完成并行調(diào)用多個遠(yuǎn)程服 務(wù)絮姆,相對多線程開銷較小醉冤,異步調(diào)用會返回一個 Future 對象。
5篙悯、一般使用什么注冊中心蚁阳?還有別的選擇嗎?
推薦使用 Zookeeper 作為注冊中心辕近,還有 Redis韵吨、Multicast、Simple 注冊中心移宅,但不推薦归粉。
6、默認(rèn)使用什么序列化框架漏峰,你知道的還有哪些糠悼?
推薦使用 Hessian 序列化,還有 Duddo浅乔、FastJson倔喂、Java 自帶序列化。
7靖苇、服務(wù)提供者能實(shí)現(xiàn)失效踢出是什么原理席噩?
服務(wù)失效踢出基于 zookeeper 的臨時節(jié)點(diǎn)原理。
8贤壁、服務(wù)上線怎么不影響舊版本悼枢?
采用多版本開發(fā),不影響舊版本脾拆。
9馒索、如何解決服務(wù)調(diào)用鏈過長的問題?
可以結(jié)合 zipkin 實(shí)現(xiàn)分布式服務(wù)追蹤名船。
10绰上、說說核心的配置有哪些?
11渠驼、Dubbo 推薦用什么協(xié)議蜈块?
dubbo://(推薦)
rmi://
hessian://
http://
webservice://
thrift://
memcached://
redis://
rest://
12、同一個服務(wù)多個注冊的情況下可以直連某一個服務(wù)嗎?
可以點(diǎn)對點(diǎn)直連疯趟,修改配置即可拘哨,也可以通過 telnet 直接某個服務(wù)。
13信峻、畫一畫服務(wù)注冊與發(fā)現(xiàn)的流程圖倦青?
14、Dubbo 集群容錯有幾種方案盹舞?
15产镐、Dubbo 服務(wù)降級,失敗重試怎么做踢步?
可以通過 dubbo:reference 中設(shè)置 mock="return null"癣亚。mock 的值也可以修改為 true,然后再跟接 口同一個路徑下實(shí)現(xiàn)一個 Mock 類获印,命名規(guī)則是 “接口名稱+Mock” 后綴述雾。然后在 Mock 類里實(shí)現(xiàn)自己 的降級邏輯
16、Dubbo 使用過程中都遇到了些什么問題兼丰?
在注冊中心找不到對應(yīng)的服務(wù),檢查 service 實(shí)現(xiàn)類是否添加了@service 注解無法連接到注冊中心,檢查 配置文件中的對應(yīng)的測試 ip 是否正確
17玻孟、Dubbo Monitor 實(shí)現(xiàn)原理?
Consumer 端在發(fā)起調(diào)用之前會先走 ?lter 鏈鳍征;provider 端在接收到請求時也是先走 ?lter 鏈黍翎,然后才 進(jìn)行真正的業(yè)務(wù)邏輯處理。
默認(rèn)情況下艳丛,在 consumer 和 provider 的 ?lter 鏈中都會有 Monitor?lter匣掸。
1、MonitorFilter 向 DubboMonitor 發(fā)送數(shù)據(jù)
2氮双、DubboMonitor 將數(shù)據(jù)進(jìn)行聚合后(默認(rèn)聚合 1min 中的統(tǒng)計數(shù)據(jù))暫存到
ConcurrentMap<Statistics, AtomicReference> statisticsMap碰酝,然后使用一個含有 3 個線程(線程名 字:DubboMonitorSendTimer)的線程池每隔 1min 鐘,調(diào)用 SimpleMonitorService 遍歷發(fā)送 statisticsMap 中的統(tǒng)計數(shù)據(jù)戴差,每發(fā)送完畢一個送爸,就重置當(dāng)前的 Statistics 的 AtomicReference 3、SimpleMonitorService 將這些聚合數(shù)據(jù)塞入 BlockingQueue queue 中(隊列大寫為 100000)
4造挽、SimpleMonitorService 使用一個后臺線程(線程名為:DubboMonitorAsyncWriteLogThread)將 queue 中的數(shù)據(jù)寫入文件(該線程以死循環(huán)的形式來寫)
5、SimpleMonitorService 還會使用一個含有 1 個線程(線程名字:DubboMonitorTimer)的線程池 每隔 5min 鐘弄痹,將文件中的統(tǒng)計數(shù)據(jù)畫成圖表
18饭入、Dubbo 用到哪些設(shè)計模式?
Dubbo 框架在初始化和通信過程中使用了多種設(shè)計模式肛真,可靈活控制類加載谐丢、權(quán)限控制等功能。
工廠模式
Provider 在 export 服務(wù)時,會調(diào)用 ServiceCon?g 的 export 方法乾忱。ServiceCon?g中有個字段:
private static final Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
Dubbo 里有很多這種代碼讥珍。這也是一種工廠模式,只是實(shí)現(xiàn)類的獲取采用了 JDKSPI 的機(jī)制窄瘟。這么實(shí)現(xiàn) 的優(yōu)點(diǎn)是可擴(kuò)展性強(qiáng)衷佃,想要擴(kuò)展實(shí)現(xiàn),只需要在 classpath下增加個文件就可以了蹄葱,代碼零侵入氏义。另
外,像上面的 Adaptive 實(shí)現(xiàn)图云,可以做到調(diào)用時動態(tài)決定調(diào)用哪個實(shí)現(xiàn)惯悠,但是由于這種實(shí)現(xiàn)采用了動態(tài) 代理,會造成代碼調(diào)試比較麻煩竣况,需要分析出實(shí)際調(diào)用的實(shí)現(xiàn)類克婶。
裝飾器模式
Dubbo 在啟動和調(diào)用階段都大量使用了裝飾器模式。以 Provider 提供的調(diào)用鏈為例丹泉,具體的調(diào)用鏈代 碼是在 ProtocolFilterWrapper 的 buildInvokerChain 完成的情萤,具體是將注解中含有 group=provider 的 Filter 實(shí)現(xiàn),按照 order 排序嘀掸,最后的調(diào)用順序是:
Dubbo 里有很多這種代碼紫岩。這也是一種工廠模式,只是實(shí)現(xiàn)類的獲取采用了 JDKSPI 的機(jī)制睬塌。這么實(shí)現(xiàn) 的優(yōu)點(diǎn)是可擴(kuò)展性強(qiáng)泉蝌,想要擴(kuò)展實(shí)現(xiàn),只需要在 classpath下增加個文件就可以了揩晴,代碼零侵入勋陪。另
外,像上面的 Adaptive 實(shí)現(xiàn)硫兰,可以做到調(diào)用時動態(tài)決定調(diào)用哪個實(shí)現(xiàn)诅愚,但是由于這種實(shí)現(xiàn)采用了動態(tài) 代理,會造成代碼調(diào)試比較麻煩劫映,需要分析出實(shí)際調(diào)用的實(shí)現(xiàn)類违孝。
裝飾器模式
Dubbo 在啟動和調(diào)用階段都大量使用了裝飾器模式。以 Provider 提供的調(diào)用鏈為例泳赋,具體的調(diào)用鏈代 碼是在 ProtocolFilterWrapper 的 buildInvokerChain 完成的雌桑,具體是將注解中含有 group=provider 的 Filter 實(shí)現(xiàn),按照 order 排序祖今,最后的調(diào)用順序是:
EchoFilter -> ClassLoaderFilter -> GenericFilter -> ContextFilter -> ExecuteLimitFilter -> TraceFilter -> TimeoutFilter -> MonitorFilter -> ExceptionFilter
更確切地說校坑,這里是裝飾器和責(zé)任鏈模式的混合使用拣技。例如,EchoFilter 的作用是判斷是否是回聲測試 請求耍目,是的話直接返回內(nèi)容膏斤,這是一種責(zé)任鏈的體現(xiàn)。而像ClassLoaderFilter 則只是在主功能上添加了 功能邪驮,更改當(dāng)前線程
的 ClassLoader莫辨,這是典型的裝飾器模式。
觀察者模式
Dubbo 的 Provider 啟動時耕捞,需要與注冊中心交互衔掸,先注冊自己的服務(wù),再訂閱自己的服務(wù)俺抽,訂閱時敞映, 采用了觀察者模式,開啟一個 listener磷斧。注冊中心會每 5 秒定時檢查是否有服務(wù)更新振愿,如果有更新,向 該服務(wù)的提供者發(fā)送一個 notify 消息弛饭,provider 接受到 notify 消息后冕末,即運(yùn)行 NotifyListener 的 notify 方法,執(zhí)行監(jiān)聽器方法侣颂。
動態(tài)代理模式
Dubbo 擴(kuò)展 JDK SPI 的類 ExtensionLoader 的 Adaptive 實(shí)現(xiàn)是典型的動態(tài)代理實(shí)現(xiàn)档桃。Dubbo 需要靈 活地控制實(shí)現(xiàn)類,即在調(diào)用階段動態(tài)地根據(jù)參數(shù)決定調(diào)用哪個實(shí)現(xiàn)類憔晒,所以采用先生成代理類的方法藻肄, 能夠做到靈活的調(diào)用。生成代理類的代碼是 ExtensionLoader 的 createAdaptiveExtensionClassCode 方法拒担。代理類的主要邏輯是嘹屯,獲取 URL 參數(shù)中指定參數(shù)的值作為獲取實(shí)現(xiàn)類的 key。
19从撼、Dubbo 配置文件是如何加載到 Spring 中的州弟?
Spring 容器在啟動的時候,會讀取到 Spring 默認(rèn)的一些 schema 以及 Dubbo 自定義的 schema低零,每 個 schema 都會對應(yīng)一個自己的 NamespaceHandler婆翔,NamespaceHandler 里面通過 BeanDe?nitionParser 來解析配置信息并轉(zhuǎn)化為需要加載的 bean 對象!
20、Dubbo SPI 和 Java SPI 區(qū)別掏婶?
JDK SPI
JDK 標(biāo)準(zhǔn)的 SPI 會一次性加載所有的擴(kuò)展實(shí)現(xiàn)啃奴,如果有的擴(kuò)展吃實(shí)話很耗時,但也沒用上气堕,很浪費(fèi)資 源纺腊。
所以只希望加載某個的實(shí)現(xiàn),就不現(xiàn)實(shí)了
DUBBO SPI
1茎芭,對 Dubbo 進(jìn)行擴(kuò)展揖膜,不需要改動 Dubbo 的源碼
2,延遲加載梅桩,可以一次只加載自己想要加載的擴(kuò)展實(shí)現(xiàn)壹粟。
3,增加了對擴(kuò)展點(diǎn) IOC 和 AOP 的支持宿百,一個擴(kuò)展點(diǎn)可以直接 setter 注入其它擴(kuò)展點(diǎn)趁仙。
4,Dubbo 的擴(kuò)展機(jī)制能很好的支持第三方 IoC 容器垦页,默認(rèn)支持 Spring Bean雀费。
21、Dubbo 支持分布式事務(wù)嗎痊焊?
目前暫時不支持盏袄,可與通過 tcc-transaction 框架實(shí)現(xiàn)
介紹:tcc-transaction 是開源的 TCC 補(bǔ)償性分布式事務(wù)框架
Git 地址:https://github.com/changmingxie/tcc-transaction
TCC-Transaction 通過 Dubbo 隱式傳參的功能,避免自己對業(yè)務(wù)代碼的入侵薄啥。
22辕羽、Dubbo 可以對結(jié)果進(jìn)行緩存嗎?
為了提高數(shù)據(jù)訪問的速度垄惧。Dubbo 提供了聲明式緩存刁愿,以減少用戶加緩存的工作量
<dubbo:reference cache="true" />
其實(shí)比普通的配置文件就多了一個標(biāo)簽 cache="true"
23、服務(wù)上線怎么兼容舊版本到逊?
可以用版本號(version)過渡铣口,多個不同版本的服務(wù)注冊到注冊中心,版本號不同的服務(wù)相互間不引 用蕾管。這個和服務(wù)分組的概念有一點(diǎn)類似枷踏。
24、Dubbo 必須依賴的包有哪些掰曾?
Dubbo 必須依賴 JDK旭蠕,其他為可選。
25旷坦、Dubbo telnet 命令能做什么掏熬?
dubbo 服務(wù)發(fā)布之后,我們可以利用 telnet 命令進(jìn)行調(diào)試秒梅、管理旗芬。Dubbo2.0.5 以上版本服務(wù)提供端口 支持 telnet 命令
連接服務(wù)
telnet localhost 20880 //鍵入回車進(jìn)入 Dubbo 命令模式。
查看服務(wù)列表
dubbo>ls
com.test.TestService
dubbo>ls com.test.TestService create
delete
query
ls (list services and methods)
ls : 顯示服務(wù)列表捆蜀。
ls -l : 顯示服務(wù)詳細(xì)信息列表疮丛。
ls XxxService:顯示服務(wù)的方法列表幔嫂。
ls -l XxxService:顯示服務(wù)的方法詳細(xì)信息列表。
26誊薄、Dubbo 支持服務(wù)降級嗎履恩?
以通過 dubbo:reference 中設(shè)置 mock="return null"。mock 的值也可以修改為 true呢蔫,然后再跟接口 同一個路徑下實(shí)現(xiàn)一個 Mock 類切心,命名規(guī)則是 “接口名稱+Mock” 后綴。然后在 Mock 類里實(shí)現(xiàn)自己的 降級邏輯
27片吊、Dubbo 如何優(yōu)雅停機(jī)绽昏?
Dubbo 是通過 JDK 的 ShutdownHook 來完成優(yōu)雅停機(jī)的,所以如果使用kill -9 PID 等強(qiáng)制關(guān)閉指令俏脊, 是不會執(zhí)行優(yōu)雅停機(jī)的全谤,只有通過 kill PID 時,才會執(zhí)行爷贫。
28啼县、Dubbo 和 Dubbox 之間的區(qū)別?
Dubbox 是繼 Dubbo 停止維護(hù)后沸久,當(dāng)當(dāng)網(wǎng)基于 Dubbo 做的一個擴(kuò)展項目季眷,如加了服務(wù)可 Restful 調(diào) 用,更新了開源組件等卷胯。
29子刮、Dubbo 和 Spring Cloud 的區(qū)別?
根據(jù)微服務(wù)架構(gòu)在各方面的要素窑睁,看看 Spring Cloud 和 Dubbo 都提供了哪些支持挺峡。
使用 Dubbo 構(gòu)建的微服務(wù)架構(gòu)就像組裝電腦,各環(huán)節(jié)我們的選擇自由度很高担钮,但是最終結(jié)果很有可能 因?yàn)橐粭l內(nèi)存質(zhì)量不行就點(diǎn)不亮了橱赠,總是讓人不怎么放心,但是如果你是一名高手箫津,那這些都不是問 題狭姨;而 Spring Cloud 就像品牌機(jī),在Spring Source 的整合下苏遥,做了大量的兼容性測試饼拍,保證了機(jī)器擁 有更高的穩(wěn)定性,但是如果要在使用非原裝組件外的東西田炭,就需要對其基礎(chǔ)有足夠的了解师抄。
30、你還了解別的分布式框架嗎教硫?
別的還有 spring 的 spring cloud叨吮,facebook 的 thrift辆布,twitter 的 ?nagle 等
31、Dubbo是什么茶鉴?
Dubbo是阿里巴巴開源的基于 Java 的高性能 RPC 分布式服務(wù)框架谚殊,現(xiàn)已成為 Apache 基金會孵化項 目。
面試官問你如果這個都不清楚蛤铜,那下面的就沒必要問了。
官網(wǎng):http://dubbo.apache.org
32丛肢、Dubbo默認(rèn)使用什么注冊中心围肥,還有別的選擇嗎?
推薦使用 Zookeeper 作為注冊中心蜂怎,還有 Redis穆刻、Multicast、Simple 注冊中心杠步,但不推薦氢伟。
33、Dubbo有哪幾種配置方式幽歼?
1)Spring 配置方式
2)Java API 配置方式
34朵锣、在 Provider 上可以配置的 Consumer 端的屬性有哪些?
1)timeout:方法調(diào)用超時
2)retries:失敗重試次數(shù)甸私,默認(rèn)重試 2 次
3)loadbalance:負(fù)載均衡算法诚些,默認(rèn)隨機(jī)
4)actives 消費(fèi)者端,最大并發(fā)調(diào)用限制
35皇型、Dubbo啟動時如果依賴的服務(wù)不可用會怎樣诬烹?
Dubbo 缺省會在啟動時檢查依賴的服務(wù)是否可用,不可用時會拋出異常弃鸦,阻止 Spring 初始化完成绞吁,默 認(rèn) check="true",可以通過 check="false" 關(guān)閉檢查唬格。
36家破、Dubbo推薦使用什么序列化框架,你知道的還有哪些购岗?
推薦使用Hessian序列化员舵,還有Duddo、FastJson藕畔、Java自帶序列化马僻。
37、Dubbo有哪幾種負(fù)載均衡策略注服,默認(rèn)是哪種韭邓?
38措近、注冊了多個同一樣的服務(wù),如果測試指定的某一個服務(wù)呢女淑?
可以配置環(huán)境點(diǎn)對點(diǎn)直連瞭郑,繞過注冊中心,將以服務(wù)接口為單位鸭你,忽略注冊中心的提供者列表屈张。
39、Dubbo支持服務(wù)多協(xié)議嗎袱巨?
Dubbo 允許配置多協(xié)議阁谆,在不同服務(wù)上支持不同協(xié)議或者同一服務(wù)上同時支持多種協(xié)議。
40愉老、當(dāng)一個服務(wù)接口有多種實(shí)現(xiàn)時怎么做场绿?
當(dāng)一個接口有多種實(shí)現(xiàn)時,可以用 group 屬性來分組嫉入,服務(wù)提供方和消費(fèi)方都指定同一個 group 即 可焰盗。
41、Dubbo服務(wù)之間的調(diào)用是阻塞的嗎咒林?
默認(rèn)是同步等待結(jié)果阻塞的熬拒,支持異步調(diào)用。
異步調(diào)用流程圖如下捌议。
Dubbo 是基于 NIO 的非阻塞實(shí)現(xiàn)并行調(diào)用垫竞,客戶端不需要啟動多線程即可完成并行調(diào)用多個遠(yuǎn)程服 務(wù)梦湘,相對多線程開銷較小,異步調(diào)用會返回一個 Future 對象件甥。
42、服務(wù)讀寫推薦的容錯策略是怎樣的?
讀操作建議使用 Failover 失敗自動切換,默認(rèn)重試兩次其他服務(wù)器化撕。
寫操作建議使用 Failfast 快速失敗,發(fā)一次調(diào)用失敗就立即報錯宫补。
43、Dubbo的管理控制臺能做什么曾我?
管理控制臺主要包含:路由規(guī)則粉怕,動態(tài)配置,服務(wù)降級抒巢,訪問控制贫贝,權(quán)重調(diào)整,負(fù)載均衡,等管理功 能稚晚。
44崇堵、說說 Dubbo 服務(wù)暴露的過程。
Dubbo 會在 Spring 實(shí)例化完 bean 之后客燕,在刷新容器最后一步發(fā)布 ContextRefreshEvent 事件的時 候鸳劳,通知實(shí)現(xiàn)了 ApplicationListener 的 ServiceBean 類進(jìn)行回調(diào) onApplicationEvent 事件方法, Dubbo 會在這個方法中調(diào)用 ServiceBean 父類 ServiceCon?g 的 export 方法也搓,而該方法真正實(shí)現(xiàn)了服 務(wù)的(異步或者非異步)發(fā)布赏廓。
45、Dubbo 停止維護(hù)了嗎傍妒?
2014 年開始停止維護(hù)過幾年幔摸,17 年開始重新維護(hù),并進(jìn)入了 Apache 項目拍顷。
46、Dubbo 能集成 Spring Boot 嗎塘幅?
可以的昔案,項目地址如下。
https://github.com/apache/incubator-dubbo-spring-boot-project
47电媳、在使用過程中都遇到了些什么問題踏揣?
Dubbo 的設(shè)計目的是為了滿足高并發(fā)小數(shù)據(jù)量的 rpc 調(diào)用,在大數(shù)據(jù)量下的性能表現(xiàn)并不好匾乓,建議使 用 rmi 或 http 協(xié)議捞稿。
48、你讀過 Dubbo 的源碼嗎拼缝?
要了解 Dubbo 就必須看其源碼娱局,了解其原理,花點(diǎn)時間看下吧咧七,網(wǎng)上也有很多教程衰齐,后續(xù)有時間我也 會在公眾號上分享 Dubbo 的源碼。
49继阻、你覺得用 Dubbo 好還是 Spring Cloud 好耻涛?
擴(kuò)展性的問題,沒有好壞瘟檩,只有適合不適合抹缕,不過我好像更傾向于使用 Dubbo, Spring Cloud 版本升級 太快,組件更新替換太頻繁墨辛,配置太繁瑣卓研,還有很多我覺得是沒有 Dubbo 順手的地方……