简介
Thrift是一个轻量级的、独立于语言的软件栈,用于点到点RPC实现。Thrift为数据传输、数据序列化和应用程序级处理提供了清晰的抽象和实现。代码生成系统使用一种简单的定义语言作为输入并生成跨编程语言的代码,这些代码使用抽象堆栈来构建可互操作的RPC客户端和服务器。
Thrift使得用不同编程语言编写的程序可以很容易地共享数据和调用远程过程。由于支持28种编程语言,Thrift很可能支持您当前使用的语言。
Thrift专门用于支持跨客户机和服务器代码的非原子版本更改。这允许你升级你的服务器,同时仍然能够服务老客户端;或者让较新的客户机向较旧的服务器发出请求。
server模型
TSimpleServer: 单线程服务器端,使用标准的阻塞式I/O。
TThreadedServer: 为每个 client 请求创建单独的线程进行I/O和业务处理。
TThreadPoolServer: 服务启动时创建线程池,其他和TThreadedServer一样。
TNonblockingServer:用libevent做事件通知,分为IOThread(调用系统I/O)和workthread(执行服务函数)。
nonblocking模式 流程解析
idl
namespace cpp demo
struct Request {
1:i32 id;
2:i64 timestamp;
3:i64 latency_us;
4:string payload;
}
struct Response {
1:i32 id;
2:i32 status;
3:i64 timastamp;
4:string payload;
}
service EchoService {
Response Echo (1:Request request);
}
图不规范,仅为自己梳理代码
client端
伪代码
new TSocket(ip, port_));
if (nonblocking) {
new TFramedTransport(TSocket);
} else {
new TBufferedTransport(TSocket);
}
new TBinaryProtocol(TTransport);
//EchoServiceClient是idl生成的client
new EchoServiceClient(protocol_);
client_->Echo(resp, req);
类图
流程图
Server端
代码
class EchoServiceHandler : public EchoServiceIf {
public:
void Echo(Response& _return, const Request& request) {
_return.payload = request.payload;
}
};
std::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(thread_nums_);
threadManager->threadFactory(std::make_shared<ThreadFactory>());
threadManager->start();
std::shared_ptr<TNonblockingServerSocket> tServerSocket = std::make_shared<TNonblockingServerSocket>(port_);
tServerSocket->setAcceptBacklog(65535);
TNonblockingServer* server_ = new TNonblockingServer(
std::make_shared<xcloud::EchoServiceProcessor>(std::make_shared<EchoServiceHandler>()),
(std::make_shared<EchoServiceHandler>()),
std::make_shared<TBinaryProtocolFactory>(),
tServerSocket,
threadManager);
server_->setNumIOThreads(iothread_nums_);
server_->serve();
一些类的说明
TProcessor:处理器是一个通用对象,它作用于两个数据流,一个是输入,另一个是输出。这个对象的定义是松散的,但典型的情况是用于生成对输入流的响应或将数据从一个管道转发到另一个管道的某种服务器。
就是通过TProcessor调用服务函数,TProcessor管理服务函数。
TServerEventHandler:虚拟接口类,可以处理来自服务器核心的事件。要使用它,您应该继承它并实现您所关心的方法。您的子类还可以存储您关心的本地数据,例如这些方法的附加“参数”(存储在对象实例的状态中)。
算是个钩子吧,Server端每一步流程都用调用TServerEventHandler相关函数。