1. 程式人生 > >聊聊RPC原理二

聊聊RPC原理二

  之前寫了一篇關於RPC的文章,瀏覽量十分感人:),但是感覺文章寫得有些粗,覺得很多細節沒有講出來,這次把裡邊的細節再次補充和說明。

  這次主要說的內容分為:

  1. RPC的主要結構圖。

  2.分析結構圖的中的細節和步驟。

  關於RPC,大家都不陌生,其簡寫和介紹什麼的我就不過多介紹了,可以從我上篇文章中看到,下面直接上我畫的圖,簡單粗暴:

  

  RPC的主要目的是將一個龐大的系統分離成不同的子系統,按照不同的功能,比如讀庫功能,記錄日誌等可以單獨出來的功能單獨出來,這樣的好處是,不會像以前那樣龐大的系統部署的時候每次都要整個系統進行重啟,可以修改單獨的模組,並且自己獨立部署,這樣大大提升效率。但是如果拆分的過細的話,可能需要維護很多的小專案,程式碼工程由一個大工程,拆分成很多小工程,而且啟動功能並且進行測試的話一般至少啟動兩個服務,一個server和一個client,同時相應的zookeeper也要啟動。

  下面來說一下上圖中每個模組的功能。

  先來說一下zookeeper, 可能有些同學已經很熟悉zookeeper使用了,當然我也在部落格中寫過zookeepr實現的鎖文章,它非常強大,但是這裡不過多解釋它強大之處,這次說它的作用。在RPC中zookeeper承擔著服務的註冊,心跳檢測,記錄client的相關資訊,最關鍵的是要記錄server的IP和埠號以及它提供service資訊,版本號等資訊。每個client在呼叫之前都要從zookeeper那裡獲取存活server的相關資訊及提供服務的版本。這樣client拿到這些資訊後可以直接和server進行通訊了。

  裡邊有一個細節就是client和server在zookeeper中註冊的znode是臨時的ephemral的,這樣的目的是在心跳檢測的時候發現client或者server已經down了,需要從zk中剔除,這樣client連線server失敗的情況下重新從zookeeper中獲取有效的server及service資訊。

  接下來就是server,在一些大型系統中,其實server是由很多臺機器構成的,這裡我為了簡化就畫了一臺機器,當server和其中部署的service啟動之後需要到zookeeper中進行註冊,這樣client就可以發現新部署的service了,通過zookeeper實現了動態的service上線和下線,是不是很厲害。在server中,由service宣告和implementation實現,同時還有在使用過程中對應的bean物件。當然在server中還部署著netty服務,這個一會兒咱們就說。

  繼續看client,client在這裡邊充當著的是consumer,就是消費service所produce的服務。client應該也是多臺的。client其實就相對比較簡單,因為是呼叫方,所以只需要宣告對應的service介面和相應的bean物件就行了。

  然後就是netty服務了,這次咱們不說netty的詳細內容,大家知道它是用來進行通訊的,擁有高吞吐量,高併發,多協議實現,並且支援NIO,AIO的工具。有興趣的同學可以讀一些關於netty的文章。netty在這裡扮演的角色就是通訊,將呼叫的service以及相關的bean物件和引數進行序列化,找到從zookeeper獲取的service所在的主機、IP、埠號、服務及版本等資訊後進行TCP連線,傳送給server後,在server中也有一個netty在對應的埠進行介面,接收後進行反序列化,然後通過動態代理實現介面呼叫,關於動態代理的實現可以參考我之前寫過的文章。呼叫之後獲取到執行結果後再以相反的順序返回去。這就是netty實現的功能了。

  這塊基本就是RPC的主要核心實現細節,當然裡邊可能還會有一些細節我沒有提到,因為RPC的功能也在不斷完善中,所以還有一些新增的一些功能沒有提及,比如server機器的比重等,這些在用到的工程中一看應該就會明白。

  好了,希望你們能從這篇文章中獲得收穫。

  歡迎轉載,但轉載請署名黃青石,謝謝。