Dubbo系列-Dubbo常見面試題

開始你的表演:


 知道什麼是 RPC 麼?

  一般面試官會以這樣的問題來切入、熱場,畢面試也是循序漸進的過程,所以你也不用太心急一開始就芭芭拉說一堆,要抓住關鍵點簡單闡述先。

  而且面試官能從這個問題鑑定出你平日的工作內容會不會連 RPC 都沒接觸過,會不會就只是一條龍的 Spring MVC ?

  確實有很多同學沒接觸過 RPC ,也很正常比如一些外包或者一些小項目都接觸不到的,不過平日接觸不到和你不知道這個東西是兩個概念。

  能從側面反映出這個人工作之餘應該不怎麼學習,連 RPC 都不知道,所以怎麼都說不過去,基本上要涼涼,對你的初始印象就差了,除非你能從後面有亮眼的表現。

答:RPC 就是 Remote Procedure Call,遠程過程調用,它相對應的是本地過程調用。

那爲什麼要有 RPC,HTTP 不好麼?

  這時候面試官就開始追問了。

  這個問題其實很有意思,有些面試官可能自己不太清楚,然後以爲自己很清楚,所以問出這個問題,還有一種是真的清楚,問這個問題是爲了讓你跳坑裏。

  因爲 RPC 和 HTTP 就不是一個層級的東西,所以嚴格意義上這兩個沒有可比性,也不應該來作比較,而題目問的就是把這兩個作爲比較了。

  HTTP 只是傳輸協議,協議只是規範了一定的交流格式,而且 RPC 是早於 HTTP 的,所以真要問也是問有 RPC 爲什麼還要 HTTP。

  RPC 對比的是本地過程調用,是用來作爲分佈式系統之間的通信,它可以用 HTTP 來傳輸,也可以基於 TCP 自定義協議傳輸。

所以你要先提出這兩個不是一個層級的東西,沒有可比性,然後再表現一下,可以說 HTTP 協議比較冗餘,所以 RPC 大多都是基於 TCP 自定義協議,定製化的纔是最適合自己的。

當然也有基於 HTTP 協議的 RPC 框架,畢竟 HTTP 是公開的協議,比較通用,像 HTTP2 已經做了相應的壓縮了,而且系統之間的調用都在內網,所以說影響也不會很大。


這波回答下來,面試官會覺得你有點東西,開始對你有點興趣了,要開始深入你了。

看過源碼,那說下服務暴露的流程?

  服務的暴露起始於 Spring IOC 容器刷新完畢之後,會根據配置參數組裝成 URL, 然後根據 URL 的參數來進行本地或者遠程調用。

  會通過 proxyFactory.getInvoker,利用 javassist 來進行動態代理,封裝真的實現類,然後再通過 URL 參數選擇對應的協議來進行 protocol.export,默認是 Dubbo 協議。

  在第一次暴露的時候會調用 createServer 來創建 Server,默認是 NettyServer。

  然後將 export 得到的 exporter 存入一個 Map 中,供之後的遠程調用查找,然後會向註冊中心註冊提供者的信息。

基本上就是這麼個流程,說了這些差不多了,太細的誰都記住不。

看過源碼,那說下服務引入的流程?

  服務的引入時機有兩種,第一種是 餓漢式,第二種是 懶漢式

  餓漢式就是加載完畢就會引入,懶漢式是隻有當這個服務被注入到其他類中時啓動引入流程,默認是 懶漢式

  會先根據配置參數組裝成 URL ,一般而言我們都會配置的註冊中心,所以會構建 RegistryDirectory 向註冊中心註冊消費者的信息,並且訂閱提供者、配置、路由等節點。

  得知提供者的信息之後會進入 Dubbo 協議的引入,會創建 Invoker ,期間會包含 NettyClient,來進行遠程通信,最後通過 Cluster 來包裝 Invoker,默認是 FailoverCluster,最終返回代理類。

說這麼多差不多了,關鍵的點都提到了。

  切忌不要太過細,不要把你知道的都說了,這樣會抓不住重點,比如上面的流程你要插入,引入的三種方式:本地引入、直連遠程引入、通過註冊中心引入。

  然後再分別說本地引入怎樣的,芭芭拉的就會很亂,所以面試的時候是需要刪減的,要直擊重點。

  其實真實說的應該比我上面說的還要精簡點纔行,我是怕大家不太清楚說的稍微詳細了一些。

看過源碼,那說下服務調用的流程?

  調用某個接口的方法會調用之前生成的代理類,然後會從 cluster 中經過路由的過濾、負載均衡機制選擇一個 invoker 發起遠程調用,此時會記錄此請求和請求的 ID 等待服務端的響應。

  服務端接受請求之後會通過參數找到之前暴露存儲的 map,得到相應的 exporter ,然後最終調用真正的實現類,再組裝好結果返回,這個響應會帶上之前請求的 ID。

  消費者收到這個響應之後會通過 ID 去找之前記錄的請求,然後找到請求之後將響應塞到對應的 Future 中,喚醒等待的線程,最後消費者得到響應,一個流程完畢。

關鍵的就是 cluster、路由、負載均衡,然後 Dubbo 默認是異步的,所以請求和響應是如何對應上的。

知道什麼是 SPI 嘛?

  這又是一個方向了,從上面的回答中,不論是從 Dubbo 協議,還是 cluster ,什麼 export 方法等等無處不是 SPI 的影子,

所以如果是問 Dubbo 方面的問題,問 SPI 是毋庸置疑的,因爲源碼裏 SPI 無處不在,而且 SPI 也是 Dubbo 可擴展性的基石。

所以這個題目沒什麼套路,直接答就行。

  SPI 是 Service Provider Interface,主要用於框架中,框架定義好接口,不同的使用者有不同的需求,因此需要有不同的實現,而 SPI 就通過定義一個特定的位置,

Java SPI 約定在 Classpath 下的 META-INF/services/ 目錄裏創建一個以服務接口命名的文件,然後文件裏面記錄的是此 jar 包提供的具體實現類的全限定名。

所以就可以通過接口找到對應的文件,獲取具體的實現類然後加載即可,做到了靈活的替換具體的實現類。

爲什麼 Dubbo 不用 JDK 的 SPI,而是要自己實現?

  問這個問題就是看你有沒有深入的瞭解,或者自己思考過,不是死板的看源碼,或者看一些知識點。

  很多點是要思考的,不是書上說什麼就是什麼,你要知道這樣做的理由,有什麼好處和壞處,這很容易看出一個人是死記硬背還是有自己的思考。

答:因爲 Java SPI 在查找擴展實現類的時候遍歷 SPI 的配置文件並且將實現類全部實例化,假設一個實現類初始化過程比較消耗資源且耗時,但是你的代碼裏面又用不上它,

這就產生了資源的浪費。

因此 Dubbo 就自己實現了一個 SPI,給每個實現類配了個名字,通過名字去文件裏面找到對應的實現類全限定名然後加載實例化,按需加載。

這答出來就加分了,面試官心裏在拍手了,不錯不錯有點東西。

Dubbo 爲什麼默認用 Javassist ?

  上面你回答 Dubbo 用 Javassist 動態代理,所以很可能會問你爲什麼要用這個代理,可能還會引申出 JDK 的動態代理、ASM、CGLIB。

  所以這也是個注意點,如果你不太清楚的話上面的回答就不要扯到動態代理了,如果清楚的話那肯定得提,來誘導面試官來問你動態代理方面的問題,這很關鍵。

  面試官是需要誘導的,畢竟他也想知道你優秀的方面到底有多優秀,你也取長補短,雙贏雙贏。

  來回答下爲什麼用 Javassist,很簡單,就是快,且字節碼生成方便。

  ASM 比 Javassist 更快,但是沒有快一個數量級,而Javassist 只需用字符串拼接就可以生成字節碼,而 ASM 需要手工生成,成本較高,比較麻煩

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章