<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          《我想進(jìn)大廠》之Dubbo普普通通9問

          共 3071字,需瀏覽 7分鐘

           ·

          2020-10-19 21:51

          這是面試專題系列第四篇,Dubbo系列。Dubbo本身并不復(fù)雜,而且官方文檔寫的非常清楚詳細(xì),面試中dubbo的問題一般不會很多,從分層到工作原理、負(fù)載均衡策略、容錯機(jī)制、SPI機(jī)制基本就差不多了,最大的一道大題一般就是怎么設(shè)計一個RPC框架了,但是如果你工作原理分層都搞明白了這個問題其實(shí)也就相當(dāng)于回答了不是嗎。

          說說Dubbo的分層?

          從大的范圍來說,dubbo分為三層,business業(yè)務(wù)邏輯層由我們自己來提供接口和實(shí)現(xiàn)還有一些配置信息,RPC層就是真正的RPC調(diào)用的核心層,封裝整個RPC的調(diào)用過程、負(fù)載均衡、集群容錯、代理,remoting則是對網(wǎng)絡(luò)傳輸協(xié)議和數(shù)據(jù)轉(zhuǎn)換的封裝。

          劃分到更細(xì)的層面,就是圖中的10層模式,整個分層依賴由上至下,除開business業(yè)務(wù)邏輯之外,其他的幾層都是SPI機(jī)制。

          能說下Dubbo的工作原理嗎?

          1. 服務(wù)啟動的時候,provider和consumer根據(jù)配置信息,連接到注冊中心register,分別向注冊中心注冊和訂閱服務(wù)

          2. register根據(jù)服務(wù)訂閱關(guān)系,返回provider信息到consumer,同時consumer會把provider信息緩存到本地。如果信息有變更,consumer會收到來自register的推送

          3. consumer生成代理對象,同時根據(jù)負(fù)載均衡策略,選擇一臺provider,同時定時向monitor記錄接口的調(diào)用次數(shù)和時間信息

          4. 拿到代理對象之后,consumer通過代理對象發(fā)起接口調(diào)用

          5. provider收到請求后對數(shù)據(jù)進(jìn)行反序列化,然后通過代理調(diào)用具體的接口實(shí)現(xiàn)

          為什么要通過代理對象通信?

          主要是為了實(shí)現(xiàn)接口的透明代理,封裝調(diào)用細(xì)節(jié),讓用戶可以像調(diào)用本地方法一樣調(diào)用遠(yuǎn)程方法,同時還可以通過代理實(shí)現(xiàn)一些其他的策略,比如:

          1、調(diào)用的負(fù)載均衡策略

          2、調(diào)用失敗、超時、降級和容錯機(jī)制

          3、做一些過濾操作,比如加入緩存、mock數(shù)據(jù)

          4、接口調(diào)用數(shù)據(jù)統(tǒng)計

          說說服務(wù)暴露的流程?

          1. 在容器啟動的時候,通過ServiceConfig解析標(biāo)簽,創(chuàng)建dubbo標(biāo)簽解析器來解析dubbo的標(biāo)簽,容器創(chuàng)建完成之后,觸發(fā)ContextRefreshEvent事件回調(diào)開始暴露服務(wù)
          2. 通過ProxyFactory獲取到invoker,invoker包含了需要執(zhí)行的方法的對象信息和具體的URL地址
          3. 再通過DubboProtocol的實(shí)現(xiàn)把包裝后的invoker轉(zhuǎn)換成exporter,然后啟動服務(wù)器server,監(jiān)聽端口
          4. 最后RegistryProtocol保存URL地址和invoker的映射關(guān)系,同時注冊到服務(wù)中心

          說說服務(wù)引用的流程?

          服務(wù)暴露之后,客戶端就要引用服務(wù),然后才是調(diào)用的過程。

          1. 首先客戶端根據(jù)配置文件信息從注冊中心訂閱服務(wù)

          2. 之后DubboProtocol根據(jù)訂閱的得到provider地址和接口信息連接到服務(wù)端server,開啟客戶端client,然后創(chuàng)建invoker

          3. invoker創(chuàng)建完成之后,通過invoker為服務(wù)接口生成代理對象,這個代理對象用于遠(yuǎn)程調(diào)用provider,服務(wù)的引用就完成了

          有哪些負(fù)載均衡策略?

          1. 加權(quán)隨機(jī):假設(shè)我們有一組服務(wù)器 servers = [A, B, C],他們對應(yīng)的權(quán)重為 weights = [5, 3, 2],權(quán)重總和為10。現(xiàn)在把這些權(quán)重值平鋪在一維坐標(biāo)值上,[0, 5) 區(qū)間屬于服務(wù)器 A,[5, 8) 區(qū)間屬于服務(wù)器 B,[8, 10) 區(qū)間屬于服務(wù)器 C。接下來通過隨機(jī)數(shù)生成器生成一個范圍在 [0, 10) 之間的隨機(jī)數(shù),然后計算這個隨機(jī)數(shù)會落到哪個區(qū)間上就可以了。

          2. 最小活躍數(shù):每個服務(wù)提供者對應(yīng)一個活躍數(shù) active,初始情況下,所有服務(wù)提供者活躍數(shù)均為0。每收到一個請求,活躍數(shù)加1,完成請求后則將活躍數(shù)減1。在服務(wù)運(yùn)行一段時間后,性能好的服務(wù)提供者處理請求的速度更快,因此活躍數(shù)下降的也越快,此時這樣的服務(wù)提供者能夠優(yōu)先獲取到新的服務(wù)請求。

          3. 一致性hash:通過hash算法,把provider的invoke和隨機(jī)節(jié)點(diǎn)生成hash,并將這個 hash 投射到 [0, 2^32 - 1] 的圓環(huán)上,查詢的時候根據(jù)key進(jìn)行md5然后進(jìn)行hash,得到第一個節(jié)點(diǎn)的值大于等于當(dāng)前hash的invoker。

          圖片來自dubbo官方
          1. 加權(quán)輪詢:比如服務(wù)器 A、B、C 權(quán)重比為 5:2:1,那么在8次請求中,服務(wù)器 A 將收到其中的5次請求,服務(wù)器 B 會收到其中的2次請求,服務(wù)器 C 則收到其中的1次請求。

          集群容錯方式有哪些?

          1. Failover Cluster失敗自動切換:dubbo的默認(rèn)容錯方案,當(dāng)調(diào)用失敗時自動切換到其他可用的節(jié)點(diǎn),具體的重試次數(shù)和間隔時間可用通過引用服務(wù)的時候配置,默認(rèn)重試次數(shù)為1也就是只調(diào)用一次。

          2. Failback Cluster快速失敗:在調(diào)用失敗,記錄日志和調(diào)用信息,然后返回空結(jié)果給consumer,并且通過定時任務(wù)每隔5秒對失敗的調(diào)用進(jìn)行重試

          3. Failfast Cluster失敗自動恢復(fù):只會調(diào)用一次,失敗后立刻拋出異常

          4. Failsafe Cluster失敗安全:調(diào)用出現(xiàn)異常,記錄日志不拋出,返回空結(jié)果

          5. Forking Cluster并行調(diào)用多個服務(wù)提供者:通過線程池創(chuàng)建多個線程,并發(fā)調(diào)用多個provider,結(jié)果保存到阻塞隊(duì)列,只要有一個provider成功返回了結(jié)果,就會立刻返回結(jié)果

          6. Broadcast Cluster廣播模式:逐個調(diào)用每個provider,如果其中一臺報錯,在循環(huán)調(diào)用結(jié)束后,拋出異常。

          了解Dubbo SPI機(jī)制嗎?

          SPI 全稱為 Service Provider Interface,是一種服務(wù)發(fā)現(xiàn)機(jī)制,本質(zhì)是將接口實(shí)現(xiàn)類的全限定名配置在文件中,并由服務(wù)加載器讀取配置文件,加載實(shí)現(xiàn)類,這樣可以在運(yùn)行時,動態(tài)為接口替換實(shí)現(xiàn)類。

          Dubbo也正是通過SPI機(jī)制實(shí)現(xiàn)了眾多的擴(kuò)展功能,而且dubbo沒有使用java原生的SPI機(jī)制,而是對齊進(jìn)行了增強(qiáng)和改進(jìn)。

          SPI在dubbo應(yīng)用很多,包括協(xié)議擴(kuò)展、集群擴(kuò)展、路由擴(kuò)展、序列化擴(kuò)展等等。

          使用方式可以在META-INF/dubbo目錄下配置:

          key=com.xxx.value

          然后通過dubbo的ExtensionLoader按照指定的key加載對應(yīng)的實(shí)現(xiàn)類,這樣做的好處就是可以按需加載,性能上得到優(yōu)化。

          如果讓你實(shí)現(xiàn)一個RPC框架怎么設(shè)計?

          1. 首先需要一個服務(wù)注冊中心,這樣consumer和provider才能去注冊和訂閱服務(wù)
          2. 需要負(fù)載均衡的機(jī)制來決定consumer如何調(diào)用客戶端,這其中還當(dāng)然要包含容錯和重試的機(jī)制
          3. 需要通信協(xié)議和工具框架,比如通過http或者rmi的協(xié)議通信,然后再根據(jù)協(xié)議選擇使用什么框架和工具來進(jìn)行通信,當(dāng)然,數(shù)據(jù)的傳輸序列化要考慮
          4. 除了基本的要素之外,像一些監(jiān)控、配置管理頁面、日志是額外的優(yōu)化考慮因素。

          那么,本質(zhì)上,只要熟悉一兩個RPC框架,就很容易想明白我們自己要怎么實(shí)現(xiàn)一個RPC框架。

          推薦閱讀

          騰訊 Git 規(guī)范出爐,寫給開發(fā)者的指南!

          最棒 Spring Boot 干貨總結(jié)(超詳細(xì),建議收藏)

          我的天,Spring Boot 居然還有 Plus 版本

          瀏覽 58
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  a亚洲网站 | 二三区高清视频 | 日韩黄色无码视频 | 久久免费看A片 | 靠逼免费看 |