Idea的提出
Thrift 存在的一些问题:
- 相比于protobuf,Thrift的序列化和反序列化性能表现欠佳,大概比protobuf慢10倍。
- 相比于其他RPC框架,Thrift拥有优秀的底层通信框架。(作者简单比较过thrift和grpc1.0的通信框架,grpc的设计实在太过简单。)
由此提出猜想和假设:
- 将 Thrift 的底层通信框架抛离出Thrift框架,利用其来构建一般性的网络应用。
- 组合 Thrift 的底层通信框架 和 protobuf序列化协议,使之成为一个新的RPC框架。
从实现难度和工作量上的考虑,本文尝试实现第一个假设,“将 Thrift 的底层通信框架抛离出Thrift框架,利用其来构建一般性的网络应用”。第二个假设希望日后,作者在时间和精力富余的时候再进行试验。
使用Thrift的网络框架搭建一般性网络应用的优点
- 快速搭建网络应用,节省时间成本
- 当Thrift协议序列化和反序列化成为系统性能瓶颈时,可对其进行替换,同时又能保留Thrift的网络框架,减少对上下游系统的影响
如何操作
有两种方法:
- 在IDL文本中,将自定义协议的结构体存为一个thrift的string变量。
- 构建自定义的Processor类
下面对这两种方法做详细介绍:
在IDL文本中,将自定义协议的结构体存为一个thrift的string变量
举例:
namespace cpp com.thrift.test
struct Parameter{
1: required string bin_data;
}
service DemoService{
i32 demoMethod(1:string param1, 2:Parameter param2);
}
将新的协议序列化后的数据放入bin_data中,这种方法缺点是,自己定义的协议,还要被thrift的序列化反序列协议包裹,不能完全消除thrift序列化和反序列化的代价。
第一种方法太过简单和粗糙,因此经过挖掘thrift代码后,探索出了更精细的方法。
构建自定义的Processor类
Thrift 底层通信模块的四大基类,TServer、TProcotol、TProcessor、TTransport,其中TProcessor::process是负责处理具体业务逻辑入口。
class TProcessor {
public:
virtual ~TProcessor() {}
virtual bool process(boost::shared_ptr<protocol::TProtocol> in,
boost::shared_ptr<protocol::TProtocol> out) = 0;
bool process(boost::shared_ptr<apache::thrift::protocol::TProtocol> io) {
return process(io, io);
}
protected:
TProcessor() {}
};
因此,只要自定义实现TProcessor的基类,重写process方法,就能自定义自己的网络应用。
下面是一个Hello world应用的简单实现:
首先实现一个HelloWorldProcessor 类。’
class HelloWordProcessor : public apache::thrift::TProcessor {
public:
virtual bool process(boost::shared_ptr<apache::thrift::protocol::tprotocol> in, boost::shared_ptr</apache::thrift::protocol::tprotocol><apache::thrift::protocol::tprotocol> out) {
out->writeBinary("Hello world!");
out->getTransport()->flush();
out->getTransport()->close();
GlobalOutput.printf("send bytes %s", "Hello world!");
return true;
}
};
然后构建main函数,本实例使用TSimpleServer模型
using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::processor;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;
int main(int argc, char **argv) {
boost::shared_ptr<tprotocolfactory> protocolFactory(new TBinaryProtocolFactory());
boost::shared_ptr<tprocessor> processor(new UwsgiProcessor());
boost::shared_ptr<tservertransport> serverTransport(new TServerSocket(9090));
boost::shared_ptr<ttransportfactory> transportFactory(new TBufferedTransportFactory());
TSimpleServer server(processor,
serverTransport,
transportFactory,
protocolFactory);
printf("Starting the server...\n");
server.serve();
printf("done.\n");
return 0;
}
最后编译、链接和运行。
简单实现一个socket客户端,发送请求,就能得到HelloWord。
性能测试
待完善
Thrift 底层通信框架的优化和调优
待完善
本文小结
作者写本文,正是在工作中遇到了一些真实的问题,比如thrift序列化反序列化慢,thrift底层那么优秀的通信框架如何更高的加以利用呢?因此带着工作中的一些问题,开始阅读thrift的源代码。
除了本文中的一些实例,作者还做了一个小的代码库,里面就用到了本文中的方法,单独使用了thrift了网络框架,Github地址如下:https://github.com/zuocheng-liu/GI。
相当精彩的博客!
好好学习,天天向上
好几年没用过博客了,支持下!
这个不错哦,我好好读读!