开源项目推荐:主流RPC开源框架及知识科普
一 什么是rpc框架?
先回答第一个问题:什么是RPC框架? 如果用一句话概括RPC就是:远程调用框架(Remote Procedure Call)
1.1 那什么是远程调用?
通常我们调用一个 c/c++ 中的函数,比如: localAdd(10, 20),localAdd方法的具体实现要么是用户自己定义的,要么是 c++ 库函数中自带的,
也就说 localAdd 函数 的代码实现在本地,它是一个本地调用!
远程调用意思就是:被调用方法的具体实现不在程序运行本地,而是在别的某个远程地方。
1.2 远程调用原理
比如 A (client) 调用 B (server) 提供的remoteAdd方法:
首先A与B之间建立一个TCP连接;
然后A把需要调用的方法名(这里是remoteAdd)以及方法参数(10, 20)序列化成字节流发送出去;
B接受A发送过来的字节流,然后反序列化得到目标方法名,方法参数,接着执行相应的方法调用(可能是localAdd)并把结果30返回;
A接受远程调用结果,输出30。
RPC框架就是把我刚才说的这几点些细节给封装起来,给用户暴露简单友好的API使用。
1.3 远程调用的优点
解耦:当修改 server 上接口实现的代码时,只要提供的接口不变,client完全感知不到,不用做任何变更;这种方式在跨部门,跨公司合作的时候经常用到。
二. rpc框架的三大要素
RPC就是要像调用本地的函数一样去调远程函数。在远程调用时,我们需要执行的函数体是在远程的机器上的,这就带来了几个新问题:
Call ID映射。在本地调用中,函数体是直接通过函数指针来指定的。在RPC中,所有的函数都必须有自己的一个ID。需要在客户端和服务端
分别维护一个 {函数 <--> Call ID} 的对应表。相同的函数对应的Call ID必须相同。客户端在做远程过程调用时,在客户端查一下这个表,找出相应的Call ID,
附带上Call ID 和参数信息,然后把它传给服务端,服务端也通过查表,根据传过来的Call ID 确定 客户端需要调用的函数,然后执行相应函数的代码。
Call ID映射 的Call ID可以直接使用函数名字符串,也可以使用整数ID。映射表一般就是一个哈希表。
序列化和反序列化。在RPC中,客户端怎么把参数值传给远程服务端的函数呢?客户端跟服务端是不同机器上的不同的进程,不能通过内存来传递参数。
甚至有时候客户端和服务端使用的都不是同一种语言(比如服务端用C++,客户端用Java或者Python)。这时候就需要客户端把参数先转成一个字节流,
传给服务端后,服务端再把字节流转成自己能读取的格式。这个过程叫序列化和反序列化。同理,从服务端返回的值也需要序列化反序列化的过程。
序列化反序列化可以自己写,也可以使用Protobuf。
网络传输。远程调用往往用在网络上,客户端和服务端是通过网络连接的。所有的数据都需要通过网络传输,因此就需要有一个网络传输层。网络传输层
需要把Call ID和序列化后的参数字节流传给服务端,然后再把序列化后的调用结果传回客户端。大部分RPC框架都使用TCP协议,但其实UDP也可以,
而gRPC干脆就用了HTTP2。Java的Netty也属于这层的东西。网络传输库可以自己写socket,或者用asio,ZeroMQ,Netty之类的网络库。
三 . 大厂流行的开源RPC框架
1、Google之gprc
https://github.com/grpc/grpc
https://github.com/google/protobuf
http://doc.oschina.net/grpc
2、Facebook之thrift
Thrift 源于Facebook,在 2007 年 Facebook 将 Thrift 作为一个开源项目提交给了 Apache 基金会。
http://thrift.apache.org/
http://thrift.apache.org/lib/
http://thrift.apache.org/lib/cpp
https://github.com/apache/thrift
3、Tencent之Tars
腾讯微服务框架Tars介绍
https://github.com/TarsCloud/Tars
https://github.com/TarsCloud/TarsCpp
https://github.com/TarsCloud/TarsGo
https://github.com/Tencent/phxrpc,前身是Svrkit
https://github.com/loveyacper/ananas 热心前腾讯大咖DIY,C++实现
4、Baidu之brpc
brpc又称为baidu-rpc,是百度开发一款“远程过程调用”网络框架。C++实现。
https://github.com/brpc/brpc
5、golang之rpcx
rpcx是一个类似阿里巴巴 Dubbo 和微博 Motan 的分布式的RPC服务框架,基于Golang net/rpc实现。号称是最好的Go语言的RPC服务治理框架,快、易用却功能强大,性能远远高于 Dubbo、Motan、Thrift等框架,是gRPC性能的两倍。
https://rpcx.io/
https://github.com/smallnest/rpcx
6、搜狗之srpc
Sogou基于Workflow的自研RPC框架,C++实现
https://github.com/sogou/srpc -- RPC based on Sogou C++ Workflow
https://github.com/sogou/workflow -- Sogou’s C++ Asynchronous Programming Engine
https://www.zhihu.com/people/liyingxin1412/
四. 其它小众的开源C++ RPC
1. RCF: 纯c++的RPC, 不引入IDL, 大量用到boost,比较强大.
2. casocklib: protobuf + asio 较完善实现
3. eventrpc: protobuf + libevent 较完善实现
https://www.exit1.org/Event-RPC/
4. evproto: protobuf + libevent 简单实现
https://github.com/chenshuo/evproto
https://github.com/chenshuo/evproto2
5. febird:同样无IDL的c++ RPC,自己实现了串行化和网络IO.
6. libHttp, xmlrpc 都是xml封装的RPC
7.rest_rpc
https://github.com/topcpporg/rest_rpc
8.muduo_rpc
https://github.com/chenshuo/muduo-protorpc
https://github.com/chenshuo/muduo/tree/master/examples/protobuf
9.other
https://github.com/IronsDu/gayrpc
https://github.com/guangqianpeng/jrpc
https://github.com/hjk41/tinyrpc
https://github.com/button-chen/buttonrpc_cpp14
https://github.com/persistentsnail/easy_pb_rpc 一个基于protocol buffer的RPC实现
http://www.cnblogs.com/persistentsnail/p/3458342.html 一个基于protocol buffer的RPC实现