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)
配置層(Config):對外配置接口晋辆,以 ServiceConfig 和 ReferenceConfig 為中心
服務(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叠必、說說核心的配置有哪些?
配置 | 配置說明 |
---|---|
dubbo:service | 服務(wù)配置 |
dubbo:reference | 引用配置 |
配置 | 配置說明 |
dubbo:protocol | 協(xié)議配置 |
dubbo:application | 應(yīng)用配置 |
dubbo:module | 模塊配置 |
dubbo:registry | 注冊中心配置 |
dubbo:monitor | 監(jiān)控中心配置 |
dubbo:provider | 提供方配置 |
dubbo:consumer | 消費(fèi)方配置 |
dubbo:method | 方法配置 |
dubbo:argument | 參數(shù)配置 |
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 集群容錯有幾種方案辟犀?
集群容錯方案 | 說明 |
---|---|
Failover Cluster | 失敗自動切換,自動重試其它服務(wù)器(默認(rèn)) |
Failfast Cluster | 快速失敗绸硕,立即報錯堂竟,只發(fā)起一次調(diào)用 |
集群容錯方案 | 說明 |
---|---|
Failsafe Cluster | 失敗安全,出現(xiàn)異常時玻佩,直接忽略 |
Failback Cluster | 失敗自動恢復(fù)出嘹,記錄失敗請求,定時重發(fā) |
Forking Cluster | 并行調(diào)用多個服務(wù)器咬崔,只要一個成功即返回 |
Broadcast Cluster | 廣播逐個調(diào)用所有提供者税稼,任意一個報錯則報錯 |
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)用之前會先走 filter 鏈揽思;provider 端在接收到請求時也是先走
filter 鏈宰闰,然后才進(jìn)行真正的業(yè)務(wù)邏輯處理。
默認(rèn)情況下郊霎,在 consumer 和 provider 的 filter 鏈中都會有 Monitorfilter沼头。
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)用 ServiceConfig 的 export 方法。ServiceConfig
中有個字段:
private static final Protocol protocol = ExtensionLoader.getExtensionLoad
er(Protocol.class).getAdaptiveExtension();
Dubbo 里有很多這種代碼档悠。這也是一種工廠模式廊鸥,只是實(shí)現(xiàn)類的獲取采用了 JDK SPI
的機(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 -> Execute
LimitFilter -> 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 里面通過 BeanDefinitionParser 來解析配置信息并轉(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)盗痒。
3,Dubbo 的擴(kuò)展機(jī)制能很好的支持第三方 IoC 容器低散,默認(rèn)支持 Spring Bean俯邓。
21、Dubbo 支持分布式事務(wù)嗎熔号?
目前暫時不支持稽鞭,可與通過 tcc-transaction 框架實(shí)現(xiàn)
介紹:tcc-transaction 是開源的 TCC 補(bǔ)償性分布式事務(wù)框架
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>lscom.test.TestServicedubbo>ls com.test.TestServicecreatedeletequery
- 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 Spring | Cloud | |
---|---|---|
服務(wù)注冊中心 | Zookeeper | Spring Cloud Netflix Eureka |
服務(wù)調(diào)用方式 | RPC | REST API |
服務(wù)網(wǎng)關(guān) | 無 | Spring Cloud Netflix Zuul |
斷路器 | 不完善 | Spring Cloud Netflix Hystrix |
分布式配置 | 無 | Spring Cloud Config |
服務(wù)跟蹤 | 無 | Spring Cloud Sleuth |
消息總線 | 無 | Spring Cloud Bus |
Dubbo | Spring Cloud | |
---|---|---|
數(shù)據(jù)流 | 無 | Spring Cloud Stream |
批量任務(wù) | 無 | Spring Cloud Task |
使用 Dubbo 構(gòu)建的微服務(wù)架構(gòu)就像組裝電腦妹卿,各環(huán)節(jié)我們的選擇自由度很高旺矾,但是最
終結(jié)果很有可能因為一條內(nèi)存質(zhì)量不行就點(diǎn)不亮了,總是讓人不怎么放心夺克,但是如果你
是一名高手箕宙,那這些都不是問題;而 Spring Cloud 就像品牌機(jī)铺纽,在 Spring Source 的
整合下柬帕,做了大量的兼容性測試,保證了機(jī)器擁有更高的穩(wěn)定性狡门,但是如果要在使用非
原裝組件外的東西陷寝,就需要對其基礎(chǔ)有足夠的了解。
30其馏、你還了解別的分布式框架嗎凤跑?
別的還有 spring 的 spring cloud,facebook 的 thrift叛复,twitter 的 finagle 等