1 萬行代碼,單機 50 萬 QPS,今年最值得學習的開源 RPC 框架!
又發現一個不錯的,工業級的,高性能 RPC 框架 srpc,分享給大家。
(1)RPC 簡介;
(2)行業常見 RPC 框架;
(3)srpc 特點;
(4)srpc 上手指南,demo 示例;
(5)srpc 架構設計;
(6)srpc 相關資料與資源;
文章較長,建議提前收藏。
什麼是 RPC?
Remote Procedure Call,遠程過程調用。
什麼是 “遠程”,爲什麼 “遠”?
先來看下什麼是 “近”,即 “本地函數調用”。
當我們寫下:
int result = Add(1, 2);
這行代碼的時候,到底發生了什麼?
(1)傳遞兩個入參;
(2)調用了本地代碼段中的函數,執行運算邏輯;
(3)返回一個出參;
這三個動作,都發生在同一個進程空間裏,這是本地函數調用。
那有沒有辦法,調用一個跨進程的函數呢?
典型的,這個進程部署在另一臺服務器上。
最容易想到的,兩個進程約定一個協議格式,使用 Socket 通信,來傳輸:
(1)入參;
(2)調用哪個函數;
(3)出參;
如果能夠實現,那這就是 “遠程” 過程調用。
爲什麼需要 RPC 框架呢?
如果沒有統一的 RPC 框架,各個團隊的服務提供方就需要各自實現一套序列化、反序列化、網絡框架、連接池、收發線程、超時處理、狀態機等 “業務之外” 的重複技術勞動,造成整體的低效。
RPC 框架的職責,就是要屏蔽各種複雜性:
(1)調用方 client 感覺就像調用本地函數一樣,來調用服務;
(2)提供方 server 感覺就像實現一個本地函數一樣,來實現服務;
有哪些常見的,出圈的 RPC 框架呢?
(1)gRPC,Google 出品,支持多語言;
(2)Thrift,Facebook 出品,支持多語言;
(3)Dubbo,阿里開源的,支持 Java;
(4)bRPC,百度開源的,支持 C++,Java;
(5)tRPC,騰訊 RPC 框架,支持多語言;
(6)...
畫外音:還有哪些?
今天和大家分享的 srpc,作者是搜狗的媛架構師 liyingxin,基於 WF,代碼量 1W 左右:
(1)非常適合用來學習 RPC 的架構設計;
(2)又是一個工業級的產品,QPS 可以到 50W,應該是行業能目前性能最好的 RPC 框架了吧,有不少超高併發的線上應用都使用它。
畫外音:不服?來戰!
什麼是 srpc?
基於 WF 的輕量級,超高性能,工業級 RPC 框架,兼容多協議,例如百度 bRPC,騰訊 tRPC,Google 的 gRPC,以及 FB 的 thrift 協議。
srpc 有些什麼特點?
(1)支持多種 IDL 格式,包括 Protobuf,Thrift 等,對於這類項目,可以一鍵遷移;
(2)支持多種序列化方式,包括 Protobuf,Thrift,json 等;
(3)支持多壓縮方法,對應用透明,包括 gzip,zlib,lz4,snappy 等;
(4)支持多協議,對應用透明,包括 http,https,ssl,tcp 等;
(5)高性能;
不同客戶端線程壓力下的性能表現非常穩定,QPS 在 50W 左右,優於同等壓測配置的 bRPC 與 thrift。
(6)輕量級,低門檻,1W 行左右代碼,只需引入一個靜態庫;
如何快速上手,體驗這個帥氣的 RPC 框架呢?
簡單來說,只需要三個步驟。
第一步:定義 IDL 描述文件。
syntax = "proto3";// proto2 or proto3
message EchoRequest {
_ string message = 1;_
_ string name = 2;_
};
message EchoResponse {
_ string message = 1;_
};
service Example {
_ rpc Echo(EchoRequest) returns (EchoResponse);_
};
第二步:生成代碼,並實現 ServiceIMPL,server 端就搞定了。
class ExampleServiceImpl : public Example::Service
{
public:
_ void Echo(EchoRequest *request,_
_ EchoResponse *response,_
_ RPCContext *ctx) override_
_ {_
_ response->set_message("Hi," + request->name());_
_ }_
};
make 一把,一氣呵成。
第三步:自己定義一個請求客戶端,向服務端發送 echo 請求。
int main()
{
_ Example::SRPCClient client("127.0.0.1", 1412);_
_ EchoRequest req;_
_ req.set_message("Hello, srpc!");_
_ req.set_name("zhangsan");_
_ client.Echo(&req, _
_ [](EchoResponse *response, RPCContext *ctx){});_
_ return 0;_
}
文末的資料集裏,有非常詳細的手冊鏈接,一步步照着來就行。
srpc 的架構設計思路是怎樣的?
作爲一個 RPC 框架,srpc 的架構是異常清晰的,用戶需要關注這 3 個層次:
(1)IDL 接口描述文件層;
(2)RPC 序列化協議層;
(3)網絡通訊層;
同時,每一層次又提供了多種選擇,用戶可以任意的組合:
如上圖所示:
(1)IDL 層,用戶可以選擇 Protobuf 或者 Thrift;
(2)協議層,可以選擇 Thrift,bRPC,tRPC 等;
畫外音:因此,才能和其他 RPC 框架無縫互通。
(3)通信層,可以選擇 tcp 或者 http;
在此分層架構之下,RPC 的客戶端要做什麼工作,RPC 的服務端要做什麼工作,srpc 框架又做了什麼工作呢?
首先必須在 IDL 中要定義好:
(1)邏輯請求包 request;
(2)邏輯響應包 response;
(3)服務接口函數 method;
RPC-client 的工作就異常簡單了:
(1)調用 method;
(2)綁定回調函數,處理回調;
對應上圖中頂部方框的綠色部分。
RPC-server 的工作也非常簡單,像實現一個本地函數一樣,提供遠程的服務:
(1)實現 method;
(2)接受 request,邏輯處理,返回 response;
對應上圖中底部方框的黃色部分。
srpc 框架完成了絕大部分的工作:
(1)對 request 序列化,壓縮,處理生成二進制報文;
(2)連接池,超時,任務隊列,異步等處理;
(3)對 request 二進制報文處理,解壓縮,反序列化;
...
對應上圖中中間的方框的紅色部分,以及大部分流程。
在這個過程中,srpc 採用插件化設計,各種複雜性細節,對接口調用方與服務提供方,都是透明的,並且具備良好的擴展性。
如上圖所示,用戶只需要關注 IDL,即邏輯請求,響應,接口的調用與實現。框架層面,將各種能力以插件的方式集成進來,向用戶提供不同能力的組合選擇。
另外,定義好 IDL 之後,服務端的代碼可以利用框架提供的工具自動生成代碼,業務服務提供方,只需要專注於業務接口的實現即可,你說帥氣不帥氣?
畫外音:具體的生成工具,與生成方法,請參看 git 上的文檔。
最後,我覺得這個 srpc 最帥氣的地方之一,就是:開源版本即線上工程版本,更新快,issue 響應快,並且文檔真的很全!
畫外音:不少大公司,公司內部的版本和開源的版本是兩套代碼,開源版本沒有文檔,KPI 完成之後,開源就沒人維護了,結果坑了一大票人。
文章的結尾,分享一些學習資源吧。
項目地址:https://github.com/sogou/srpc
項目 demo:
README_cn.md
項目架構設計:
docs/wiki.md
作者知乎:
https://www.zhihu.com/people/liyingxin1412/posts
作者聯繫方式:
發現 bug 可以隨時提交給她,響應絕對快速。
項目地址:https://github.com/sogou/srpc
Star:800+
畫外音:srpc 還有很多優秀的設計,等待大家去挖掘。
末了,希望這個 1W 行代碼的 RPC 框架,能夠幫助大家更透徹的瞭解 RPC 的底層原理。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/ax1646PKHdTkRu6Pv8ijrQ