Spring Eureka 從開源轉變為閉源,Consul 正在崛起,而 Dubbo 又開始重新更新。目前市場上仍有不少公司使用dubbo我們也需要繼續學習。
1、為什麼要用Dubbo?
隨著服務化的進一步發展,服務越來越多,服務之間的呼叫和依賴關係也越來越複雜,誕生了面向服務的架構體系(SOA),
也因此衍生出了一系列相應的技術,如對服務提供、服務呼叫、連線處理、通訊協議、序列化方式、服務發現、服務路由、日誌輸出等行為進行封裝的服務框架。
就這樣為分散式系統的服務治理框架就出現了,Dubbo也就這樣產生了。
2、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
3、預設使用的是什麼通訊框架,還有別的選擇嗎?
預設也推薦使用netty框架,還有mina。
4、服務呼叫是阻塞的嗎?
預設是阻塞的,可以非同步呼叫,沒有返回值的可以這麼做。
Dubbo 是基於 NIO 的非阻塞實現並行呼叫,客戶端不需要啟動多執行緒即可完成並行呼叫多個遠端服務,相對多執行緒開銷較小,非同步呼叫會返回一個 Future 物件。
5、一般使用什麼註冊中心?還有別的選擇嗎?
推薦使用 Zookeeper 作為註冊中心,還有 Redis、Multicast、Simple 註冊中心,但不推薦。
6、預設使用什麼序列化框架,你知道的還有哪些?
推薦使用Hessian序列化,還有Duddo、FastJson、Java自帶序列化。
7、服務提供者能實現失效踢出是什麼原理?
服務失效踢出基於zookeeper的臨時節點原理。
8、服務上線怎麼不影響舊版本?
採用多版本開發,不影響舊版本。
9、如何解決服務呼叫鏈過長的問題?
可以結合zipkin實現分散式服務追蹤。
10、說說核心的配置有哪些?
配置 | 配置說明 |
---|---|
dubbo:service | 服務配置 |
dubbo:reference | 引用配置 |
dubbo:protocol | 協議配置 |
dubbo:application | 應用配置 |
dubbo:module | 模組配置 |
dubbo:registry | 註冊中心配置 |
dubbo:monitor | 監控中心配置 |
dubbo:provider | 提供方配置 |
dubbo:consumer | 消費方配置 |
dubbo:method | 方法配置 |
dubbo:argument | 引數配置 |
11、Dubbo 推薦用什麼協議?
- dubbo://(推薦)
- rmi://
- hessian://
- http://
- webservice://
- thrift://
- memcached://
- redis://
- rest://
12、同一個服務多個註冊的情況下可以直連某一個服務嗎?
可以點對點直連,修改配置即可,也可以通過telnet直接某個服務。
13、畫一畫服務註冊與發現的流程圖?
14、Dubbo 叢集容錯有幾種方案?
叢集容錯方案 | 說明 |
---|---|
Failover Cluster | 失敗自動切換,自動重試其它伺服器(預設) |
Failfast Cluster | 快速失敗,立即報錯,只發起一次呼叫 |
Failsafe Cluster | 失敗安全,出現異常時,直接忽略 |
Failback Cluster | 失敗自動恢復,記錄失敗請求,定時重發 |
Forking Cluster | 並行呼叫多個伺服器,只要一個成功即返回 |
Broadcast Cluster | 廣播逐個呼叫所有提供者,任意一個報錯則報錯 |
15、Dubbo 服務降級,失敗重試怎麼做?
可以通過dubbo:reference 中設定 mock="return null"。mock 的值也可以修改為 true,然後再跟介面同一個路徑下實現一個 Mock 類,命名規則是 “介面名稱+Mock” 字尾。然後在 Mock 類裡實現自己的降級邏輯
16、Dubbo 使用過程中都遇到了些什麼問題?
在註冊中心找不到對應的服務,檢查service實現類是否新增了@service註解 無法連線到註冊中心,檢查配置檔案中的對應的測試ip是否正確
17、Dubbo Monitor 實現原理?
Consumer端在發起呼叫之前會先走filter鏈;provider端在接收到請求時也是先走filter鏈,然後才進行真正的業務邏輯處理。
預設情況下,在consumer和provider的filter鏈中都會有Monitorfilter。
1、MonitorFilter向DubboMonitor傳送資料 2、DubboMonitor將資料進行聚合後(預設聚合1min中的統計資料)暫存到ConcurrentMap<Statistics, AtomicReference> statisticsMap,然後使用一個含有3個執行緒(執行緒名字:DubboMonitorSendTimer)的執行緒池每隔1min鍾,呼叫SimpleMonitorService遍歷傳送statisticsMap中的統計資料,每傳送完畢一個,就重置當前的Statistics的AtomicReference 3、SimpleMonitorService將這些聚合資料塞入BlockingQueue queue中(佇列大寫為100000) 4、SimpleMonitorService使用一個後臺執行緒(執行緒名為:DubboMonitorAsyncWriteLogThread)將queue中的資料寫入檔案(該執行緒以死迴圈的形式來寫) 5、SimpleMonitorService還會使用一個含有1個執行緒(執行緒名字:DubboMonitorTimer)的執行緒池每隔5min鍾,將檔案中的統計資料畫成圖表
18、Dubbo 用到哪些設計模式?
Dubbo框架在初始化和通訊過程中使用了多種設計模式,可靈活控制類載入、許可權控制等功能。
工廠模式 Provider在export服務時,會呼叫ServiceConfig的export方法。ServiceConfig中有個欄位:
private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
複製程式碼
Dubbo裡有很多這種程式碼。這也是一種工廠模式,只是實現類的獲取採用了JDK SPI的機制。這麼實現的優點是可擴充套件性強,想要擴充套件實現,只需要在classpath下增加個檔案就可以了,程式碼零侵入。另外,像上面的Adaptive實現,可以做到呼叫時動態決定呼叫哪個實現,但是由於這種實現採用了動態代理,會造成程式碼除錯比較麻煩,需要分析出實際呼叫的實現類。
裝飾器模式 Dubbo在啟動和呼叫階段都大量使用了裝飾器模式。以Provider提供的呼叫鏈為例,具體的呼叫鏈程式碼是在ProtocolFilterWrapper的buildInvokerChain完成的,具體是將註解中含有group=provider的Filter實現,按照order排序,最後的呼叫順序是:
EchoFilter -> ClassLoaderFilter -> GenericFilter -> ContextFilter -> ExecuteLimitFilter -> TraceFilter -> TimeoutFilter -> MonitorFilter -> ExceptionFilter
複製程式碼
更確切地說,這裡是裝飾器和責任鏈模式的混合使用。例如,EchoFilter的作用是判斷是否是回聲測試請求,是的話直接返回內容,這是一種責任鏈的體現。而像ClassLoaderFilter則只是在主功能上新增了功能,更改當前執行緒的ClassLoader,這是典型的裝飾器模式。
觀察者模式 Dubbo的Provider啟動時,需要與註冊中心互動,先註冊自己的服務,再訂閱自己的服務,訂閱時,採用了觀察者模式,開啟一個listener。註冊中心會每5秒定時檢查是否有服務更新,如果有更新,向該服務的提供者傳送一個notify訊息,provider接受到notify訊息後,即執行NotifyListener的notify方法,執行監聽器方法。
動態代理模式 Dubbo擴充套件JDK SPI的類ExtensionLoader的Adaptive實現是典型的動態代理實現。Dubbo需要靈活地控制實現類,即在呼叫階段動態地根據引數決定呼叫哪個實現類,所以採用先生成代理類的方法,能夠做到靈活的呼叫。生成代理類的程式碼是ExtensionLoader的createAdaptiveExtensionClassCode方法。代理類的主要邏輯是,獲取URL引數中指定引數的值作為獲取實現類的key。
19、Dubbo 配置檔案是如何載入到Spring中的?
Spring容器在啟動的時候,會讀取到Spring預設的一些schema以及Dubbo自定義的schema,每個schema都會對應一個自己的NamespaceHandler,NamespaceHandler裡面通過BeanDefinitionParser來解析配置資訊並轉化為需要載入的bean物件!
20、Dubbo SPI 和 Java SPI 區別?
JDK SPI JDK 標準的 SPI 會一次性載入所有的擴充套件實現,如果有的擴充套件吃實話很耗時,但也沒用上,很浪費資源。
所以只希望載入某個的實現,就不現實了
DUBBO SPI 1,對Dubbo進行擴充套件,不需要改動Dubbo的原始碼 2,延遲載入,可以一次只載入自己想要載入的擴充套件實現。 3,增加了對擴充套件點 IOC 和 AOP 的支援,一個擴充套件點可以直接 setter 注入其它擴充套件點。 3,Dubbo的擴充套件機制能很好的支援第三方IoC容器,預設支援Spring Bean。
21、Dubbo 支援分散式事務嗎?
目前暫時不支援,可與通過 tcc-transaction框架實現
介紹:tcc-transaction是開源的TCC補償性分散式事務框架
Git地址:https://github.com/changmingxie/tcc-transaction
TCC-Transaction 通過 Dubbo 隱式傳參的功能,避免自己對業務程式碼的入侵。
22、Dubbo 可以對結果進行快取嗎?
為了提高資料訪問的速度。Dubbo提供了宣告式快取,以減少使用者加快取的工作量
<dubbo:reference cache="true" />
其實比普通的配置檔案就多了一個標籤 cache="true"
23、服務上線怎麼相容舊版本?
可以用版本號(version)過渡,多個不同版本的服務註冊到註冊中心,版本號不同的服務相互間不引用。這個和服務分組的概念有一點類似。
24、Dubbo必須依賴的包有哪些?
Dubbo 必須依賴 JDK,其他為可選。
25、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:顯示服務的方法詳細資訊列表。
26、Dubbo 支援服務降級嗎?
以通過dubbo:reference 中設定 mock="return null"。mock 的值也可以修改為 true,然後再跟介面同一個路徑下實現一個 Mock 類,命名規則是 “介面名稱+Mock” 字尾。然後在 Mock 類裡實現自己的降級邏輯
27、Dubbo 如何優雅停機?
Dubbo 是通過 JDK 的 ShutdownHook 來完成優雅停機的,所以如果使用 kill -9 PID 等強制關閉指令,是不會執行優雅停機的,只有通過 kill PID 時,才會執行。
28、Dubbo 和 Dubbox 之間的區別?
Dubbox 是繼 Dubbo 停止維護後,噹噹網基於 Dubbo 做的一個擴充套件專案,如加了服務可 Restful 呼叫,更新了開源元件等。
29、Dubbo 和 Spring Cloud 的區別?
根據微服務架構在各方面的要素,看看Spring Cloud和Dubbo都提供了哪些支援。
Dubbo | Spring Cloud | |
---|---|---|
服務註冊中心 | Zookeeper | Spring Cloud Netflix Eureka |
服務呼叫方式 | RPC | REST API |
服務閘道器 | 無 | Spring Cloud Netflix Zuul |
斷路器 | 不完善 | Spring Cloud Netflix Hystrix |
分散式配置 | 無 | Spring Cloud Config |
服務跟蹤 | 無 | Spring Cloud Sleuth |
訊息匯流排 | 無 | Spring Cloud Bus |
資料流 | 無 | Spring Cloud Stream |
批量任務 | 無 | Spring Cloud Task |
使用Dubbo構建的微服務架構就像組裝電腦,各環節我們的選擇自由度很高,但是最終結果很有可能因為一條記憶體質量不行就點不亮了,總是讓人不怎麼放心,但是如果你是一名高手,那這些都不是問題;而Spring Cloud就像品牌機,在Spring Source的整合下,做了大量的相容性測試,保證了機器擁有更高的穩定性,但是如果要在使用非原裝元件外的東西,就需要對其基礎有足夠的瞭解。
30、你還了解別的分散式框架嗎?
別的還有spring的spring cloud,facebook的thrift,twitter的finagle等