- 0
- 0
- 约8.36千字
- 约 5页
- 2020-03-19 发布于江苏
- 举报
SimpleRpc-客户端与服务端工作模型探讨
阿里巴巴首席工程师经验分享,物超所值。
前言
本篇文章讲述客户端与服务端的具体设计细节。有细心的小伙伴发现,客户端和服务端的工作方式不一样:服务端是多线程计算模型,利用工作线程完成数据的读取,而客户端是单线程(利用Reactor线程完成数据的读取)。这么做的原因有二:首先我们认为我们的使用RPC的初衷是由于CPU计算是瓶颈,不得已把计算放到多台机器上,所以服务端采用多线程计算模型;其次我们认为网络IO只要不是客户端故意阻塞,那么无论是请求数据还是响应数据只需要一次接收就可以收全,不会有线程长时间阻塞在网络上,所以客户端就使用反应器线程进行接收响应数据。
客户端同步和异步调用
SimpleRpc提供了同步调用和异步调用的方法,使用区别在于传递的参数不同,如下所示。
//异步请求
int async_request(Server server, Request *request, Response *response, ResultHandler *handler);
//同步请求
int sync_request(Server server, Request *request, Response *response);
那么SimpleRpc对于同步和异步调用是如何支持的呢?我们重新看一下DownstreamHandler对数据的处理方式:
void DownstreamHandler::handle_read(int fd) {
char head[4];
Connection conn(fd);
conn.recv_n(head, 4);
int size = *((int *)head);
char *buf = new char[size];
conn.recv_n(buf, size);
close(fd);
printf(Downstream Handler close fd:%d\n, fd);
//下游响应
_response-deserialize(buf, size);
//如果有result_handler,则调用data_comeback钩子函数
if(_result_handler != NULL) {
_result_handler-data_comeback(); //对于同步调用,这个方法会唤醒客户端使其从wait中返回
}
delete[] buf;
//自杀
delete this;
}
result_handler的调用是关键,我们正是利用这一点做到同步调用和异步调用。ResultHandler的类UML如下:
DefaultResul
原创力文档

文档评论(0)