如何用一天時間實現自己的RPC框架

haolujun發表於2017-09-21

前言


最近,閒來無事,自己寫了一個簡單的RPC框架,我把它叫做SimpleRpc。它有多簡單?一共只有1400行程式碼。這個RPC只是作為自己試驗作品,交流技術之用,當然如果你敢用,也可以放到生產環境之中,只不過要自求多福。

現在有很多開源的RPC,我用過的有ICE,thrift,grpc。我知道有很多小夥伴想閱讀以上這些開源專案的原始碼,但是一頭扎進去,難免會迷了方向,畢竟這些成熟的RPC考慮了很多東西,很容易讓人陷入到某個細節不能自拔,對於理解主幹反而是一種累贅。所以,我的這個SimpleRpc就是要精簡精簡再精簡,把這些RPC的骨骼抽出來,忽略一些可用性、易用性、移植性,目的只是要小夥伴們理解RPC的主要工作流程,克服對RPC設計的恐懼。我相信,如果小夥伴們看完這個簡單的不能再簡單的設計後,自己也能順手寫出一個RPC。

寫作思路


 如果只用一篇部落格寫完這個SimpleRpc的實現,將會使得這個部落格又臭又長,小夥伴們很難一下子全部消化掉。所以,我準備一一系列部落格寫完這個RPC,這樣做的好處在於可以在每篇部落格中詳細講一個設計要點,每個部分都成為一個單獨的設計點存在,這樣就使得這個設計有主次之分,有階段性理解。

當然,我在本篇部落格中附件中附上原始碼,小夥伴可以去看:https://github.com/haolujun/SimpleRpc

SimpleRpc-系統邊界以及整體架構

SimpleRpc-序列化與反序列化的設計與實現

SimpleRpc-網路事件響應Reactor設計模式

SimpleRpc-客戶端與服務端工作模型探討

使用樣例


在進行具體介紹之前,我們先貼上客戶端與服務端的樣例程式碼,讓大家熟悉一下這個rpc的使用方法。我們開發一個做加法計算的服務和客戶端,客戶端每次傳送給服務端兩個數字,服務端把相加後得到的結果返回給客戶端。

客戶端程式碼:

 1 #include <string>                                   
 2 #include "Add.h"
 3 #include "SimpleRpc.h"                                                                                               
 4 
 5 int main(){
 6   Server server(
 7     std::string("add"), 
 8     std::string("add"), 
 9     std::string("127.0.0.1"), 
10     std::string("27008")
11   );     
12   
13   CalcRequest req;                                
14   req.set_a(100);                      
15   req.set_b(100);
16   AddRequest add_request;
17   AddResponse add_response;
18   add_request.set_req(req);
19 
20   for(int i = 0; i < 10; ++i) {
21     SimpleRpcClient::get_instance()->request(
22       server, (Request*)&add_request, (Response*)&add_response);
23     printf("result = %d\n", add_response.get_response().result());
24   }
25 
26   return 0;
27 }

服務端程式碼:

 1 #include "Add.h"
 2 #include "SimpleRpc.h"                                 
 3 
 4 int main(){
 5   std::string service_name("add");
 6   SimpleRpcService<AddRequest, AddResponse, AddProcessorFactory> *service_add;
 7   service_add = new SimpleRpcService<AddRequest, AddResponse, AddProcessorFactory>(                                  
 8     std::string("27008"), service_name);
 9   service_add->start();
10   return 0;

當然這裡面忽略了一些額外還需要我們寫的程式碼,我只要給各位小夥伴留一個直白印象。除了標記成紅色的類之外,小夥伴還需實現AddProcessor這個類即可。AddProcessor類如下:

class AddProcessor : public Processor<AddRequest, AddResponse>{                                                      
  public:
    int process(AddRequest &request, AddResponse &response) {                                                        
      CalcRequest req = request.get_req();                                                                           
      CalcResponse resp;
      resp.set_result(req.a() + req.b());                                                                            
      response.set_response(resp);                                                                                   
      return 0;                                                                                                      
    }                                                                                                                
}

 

相關文章