頻道欄目
首頁 > 資訊 > 其他綜合 > 正文

基于netty的高性能RPC服務器技術簡介

17-02-14        來源:[db:作者]  
收藏   我要投稿

基于netty的高性能RPC服務器技術簡介:RPC 遠程過程調用協議,是一種通過網絡,向遠程計算機程序上請求服務,而不必了解底層網絡技術的協議。簡單點說就是客戶端在不必知道調用細節的前提下,調用遠程計算機上運行的某個對象,使用起來就像調用本地的對象一樣。

目前典型的RPC框架有Facebook開源的Thrift、阿里巴巴的Dubbo等等。RPC針對網絡協議和網絡IO是透明的,對于調用的客戶端而言仿佛就是在調用本地的對象一樣。 在傳輸層網絡協議上運行的是TCP協議、UDP協議亦或是Http協議不關心。 在網絡IO模型上,是基于select、poll還是epoll方式都不需要關心。

目前主流的RPC框架都支持跨語言的調用,適用于異構系統。在影響一個RPC框架性能中,RPC網絡IO的選擇至關重要,在網絡IO的基礎上可以支持同步阻塞IO、非阻塞同步IO、多路復用IO模型和異步IO模型。此外傳輸協議選擇上,目前主流的都是基于TCP協議。

以上基本上描述清楚了RPC服務器是個什么東西,現在我就使用Java,基于高性能NIO框架netty 做一個高性能的RPC服務器。

在開始做之前我們需要考慮一些問題:
1)怎么實現、基于什么原理?
2)并發性能怎么樣?

為了提高通信的性能,基于Java我們一般都是使用Java的NIO,但是JDK中的NIO使用不太方便,并且使用起來需要對NIO有很深的技術功底,所以我們一般首選Java的NIO框架netty,而且netty還能幫我們解決TCP粘包、網絡通信異常、消息鏈接處理等等網絡通信細節問題。netty也是基于TCP,對于處理高并發也是綽綽有余。這里我基于netty4來進行開發。

下面先來簡單介紹一下技術原理:

1.技術原理

(1)定義RPC 請求消息、 應答消息的結構, RPC接口里面需要包括:接口唯一ID標識、遠程調用類名、方法名、參數結構、參數值等信息。

(2)服務端初始化的時候會通過Spring加載RPC接口定義和實現類對象的映射關系,然后等待客戶端發起調用請求。

(3)客戶端將請求消息體通過網絡以字節流的方式發送給RPC服務器。

(4)服務端收到客戶端的請求消息后,根據消息體的內容到容器中找對應的具體實現對象。RPC服務端找到實現對象的參數信息,通過反射機制創建該對象的實例,并返回調用處理結果,最后封裝成RPC應答消息通知到客戶端。

(5)客戶端通過網絡接收響應消息,進行解碼然后顯示調用結果。



上面的介紹說的很簡單,但是具體實現起來有很多問題需要考慮,比如:
(1)我們是基于TCP來進行數據傳輸的,很典型的在TCP的底層如果出現了黏包怎么辦?基于netty怎么解決?好在netty給出了解決方案,使用LengthFieldBasedFrameDecoder解碼器

(2)netty的服務端線程模型是單線程、多線程(一個線程負責處理客戶端連接,然后丟給后臺的IO處理線程池處理)、還是主從模式(客戶端連接、后端IO處理都是基于線程池的實現)。這里為了提高性能,我們使用了netty的主從線程池模型

(3)netty的IO處理線程池,如果碰到了非常耗時的業務出現了阻塞怎么辦?這就很容易把后端的NIO線程給掛死。這里為了處理這種問題,用到了Java的異步回調功能,將業務直接分派到業務線程池處理,處理完后異步回調處理。

(4)RPC請求和響應消息的編碼和解碼字節流使用哪一種方式?原生的Java序列化,還是更加優秀的開源方式,比如Google的protobuf。 這里因為不涉及到異構系統,為了方便起見首先使用JDK原生序列化方式。

(5)服務端得考慮在多線程和高并發情況下的處理,所以必須是線程安全的,獲得線程安全的程序就肯定會涉及到加鎖。這里不適用原生提供的悲觀鎖synchronized, 而使用輕量級的顯示鎖ReentrantLock對代碼塊加鎖。

下面通過一個示意圖來表示服務端接收客戶端的請求之后的處理流程:
服務端接收客戶端并發請求后處理過程示意圖

服務端的netty連接器接收到了客戶端的并發請求之后,由netty分發出N個NIO連接線程,這時候netty的連接器任務就結束了。之后把這N個NIO連接線程統一的加入netty的NIO處理線程池進行管理,在NIO處理線程池對請求消息進行解碼或則編碼等操作。

之后再分派給單獨的Handler線程來進行處理,這里的handler線程也就是我們自己實現的handler。在handler進行消息處理的時候,為了提高性能,防止耗時任務的阻塞,這里直接把復雜的消息處理過程丟給我自己實現的專門的RPC業務處理線程池來處理,然后handler對應的NIO線程立即返回不阻塞。當RPC業務處理線程池結束之后通過回調機制異步通知客戶端請求結果。

在netty的服務端程序中,最核心的就是handler的實現,也就是核心業務的處理,這里對netty中對RPC請求和響應的編解碼過程中涉及到的編解碼器和流程做一個分析。(這里使用的是基于JDK原生序列化來序列化消息數據)。

相關TAG標簽
上一篇:臺積電:絕大多數7nm客戶都會轉向6nm_IT新聞_博客園
下一篇:最后一頁
相關文章
圖文推薦

關于我們 | 聯系我們 | 廣告服務 | 投資合作 | 版權申明 | 在線幫助 | 網站地圖 | 作品發布 | Vip技術培訓 | 舉報中心

版權所有: 紅黑聯盟--致力于做實用的IT技術學習網站

美女MM131爽爽爽毛片