简单介绍google protobuf rpc框架使用方法

来源:互联网 发布:软件app如何推广 编辑:程序博客网 时间:2024/05/23 10:53

对google protobuf定义的基本rpc框架学习了一下

基本rpc定义

  • RpcController
    • An RpcController mediates a single method call. The primary purpose of the controller is to provide a way to manipulate settings specific to the RPC implementation and to find out about RPC-level errors.
    • The methods provided by the RpcController interface are intended to be a “least common denominator” set of features which we expect all implementations to support. Specific implementations may provide more advanced features (e.g. deadline propagation). // 给出最少必须实现的基类
    • 分为servise-side方法和client-side方法两类,提供交互情况
      • 在Client每次调用方法时,都需要传入一个RpcController,其作用是:
        • Client端在发送请求前
          • 控制请求的超时时间
          • 设置Request或者Response的压缩类型;
        • Client端在请求完成后
          • 获取(成功/失败)状态,如果失败可获取错误信息,检查请求是否已发送至远端;
      • 在Server端在服务实现内:
        • 获取client端的地址,设置失败标志;
    • 注意事项
      • RpcController用于控制单次请求,因此每次RPC请求(无论同步还是异步)都需要一个RpcController,在本次请求完成前,其不得释放或者重用;
      • 请求完成后,该RpcController可以使用Reset()方法恢复初始状态以进行重用;
      • RpcController的不同接口有不同的使用时间范围,只有在规定的时间范围内使用,接口才能返回正确结果,否则行为是不确定的;
  • RpcChannel

    • Abstract interface for an RPC channel. An RpcChannel represents a communication line to a Service which can be used to call that Service’s methods. The Service may be running on another machine. Normally, you should not call an RpcChannel directly, but instead construct a stub Service wrapping it.
    • CallMethod必须定义,用来序列化反序列化数据和发送数据。RPC客户端需要实现google::protobuf::RpcChannel。主要实现RpcChannel::CallMethod接口。客户端调用任何一个RPC接口,最终都是调用到CallMethod。这个函数的典型实现就是将RPC调用参数序列化,然后投递给网络模块进行发送。
    • 自定义

          void CallMethod(const ::google::protobuf::MethodDescriptor* method,                      ::google::protobuf::RpcController* controller,                      const ::google::protobuf::Message* request,                      ::google::protobuf::Message* response,                      ::google::protobuf::Closure* done) {        ...        // 只是示例,总之这个地方是发送请求,可以看你是实现异步还是同步。。        DataBufferOutputStream outputStream(...) // 取决于你使用的网络实现        request->SerializeToZeroCopyStream(&outputStream);        _connection->postData(outputStream.getData(), ...        ...    }
    • Example

         RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234");   MyService* service = new MyService::Stub(channel);   service->MyMethod(request, &response, callback);
  • Service

    • Abstract base interface for protocol-buffer-based RPC services. Services themselves are abstract interfaces (implemented either by servers or as stubs), but they subclass this base interface. The methods of this interface can be used to call the methods of the Service without knowing its exact type at compile time (analogous to Reflection).
    • server端

      • 服务端需实现所有的rpc调用方法
           class MyServiceImpl : public MyService {       // 实现proto中声明的方法       virtual void Echo(::google::protobuf::RpcController* controller,           const EchoReqMsg* request,           EchoRespMsg* response,           ::google::protobuf::Closure* done) {           ...           done->Run();           // 注意调了done->Run()之后,所有的四个参数都不再能访问。       }   }
    • client端

      • stub代码为自动生成代码,其中依赖RpcChannel中的CallBack方法去实现远程方法调用

            void EchoService_Stub::Foo(::google::protobuf::RpcController* controller,                                  const ::FooRequest* request,                                  ::FooResponse* response,                                  ::google::protobuf::Closure* done) {        channel_->CallMethod(descriptor()->method(0),                           controller, request, response, done);    }

        示意图


扩展

  • 上面只是简单地交互,要想实现一个完整的rpc通信框架需要丰富很多内容
    • proto定义
      • 考虑一个连接多次方法调用,由于服务端并不知道客户端想要调用哪一个RPC接口 ,此时需要在通信时携带rpc端口标识
    • 需要框架实现(参考sofa-rpc功能)
      • 内存管理:如读写缓冲区、request/response管理、message queue之类的。。。
      • 多任务调度??
      • 支持同步or异步调用
      • 多级超时设定,超时控制更灵活
      • 流量控制
      • 支持透明压缩传输,节省带宽
      • 连接管理
        • 自动建立连接、自动重连
        • 空闲连接自动关闭
        • 连接探活
      • ……

参考连接

  • http://www.blogjava.net/DLevin/archive/2015/04/01/424012.html
  • http://blog.csdn.net/x875227668/article/details/48438521
  • http://blog.csdn.net/nk_test/article/details/72682780
原创粉丝点击