簡單聊下 RPC 實現
相信大家或多或少都接觸過RPC(Remote Procedure Call)框架,業務發展到一定階段,都或多或少做過一些服務化的事情。(如果有不瞭解的,自行google去,這裡就不詳細說明了)
大家用的同時,可能很少人會去思考RPC框架怎麼去實現的呢?
首先一個簡單的遠端服務呼叫中間會經過哪些流程呢?
客戶端序列化-》序列化過程中建立二進位制陣列-》陣列需要在jvm堆記憶體以及堆外記憶體建立-》客戶端把序列化好的陣列傳送給服務端,所以高效能的序列化框架很重要-》服務端接入請求,這裡又涉及到怎麼同時處理多個客戶端接入請求,I/O多路複用技術就起到了作用-》服務端讀取碼流,這裡又涉及到解碼,怎麼與客戶端協定好通訊協議呢-》服務端通過反射的方式呼叫服務提供者實現類,反射本身對效能影響就非常大,這裡又涉及怎麼去優化。-》等等
實際上整個RPC過程,複雜的多,上面只是帶起大家的思考。
下面簡單說下實現RPC框架很重要的幾點。
如何註冊釋出服務?
可能瞭解zookeeper同學會說,用zookeeper就可以實現服務自動註冊與發現功能。zookeeper簡單來說就是個檔案系統,儲存了ip+埠。本身選舉機制也很大保證了服務登錄檔的高可用。
無縫呼叫服務
遠端服務怎麼與本地服務一樣無縫呼叫呢?這裡就涉及到了java動態代理,代理類封裝了通訊的細節,讓消費端直接呼叫。
序列化
實現高能化的序列化框架不是很容易的,序列化後的碼流大小,效能,是否支援誇語言,併發呼叫的效能表現。實踐使用過程中,一般是二進位制序列化框架,比如Protobuf等,感興趣的可以去了解下。
通訊
目前有兩種常用IO通訊模型:1)BIO;2)NIO。一般RPC框架需要支援這兩種IO模型。
目前主流的rpc框架都是基於netty來的,netty的零拷貝,記憶體池,無鎖化的序列設計等都使它有很大的效能優勢。
後面我會出篇文章細講下關於netty的原理,以及RPC程式碼級的實現。 如果你覺得有點收穫,不妨關注下公眾號。