rpc-server端IO服务模型实现:epoll线程池
2018-01-29 16:16
1366 查看
(一)功能
rpc(远程函数调用)提供client端通过网络调用远程server端的函数的服务。
rpc-server端需要提供较高的吞吐能力,支持较大的并发连接。
(二)设计思路
epoll监听多个连接fd,实现IO复用
1)epoll没有最大并发连接的限制,上限是最大可以打开文件的数目,一般远大于2048
2)epoll效率高,只管活跃的连接,而跟连接总数无关
3)使用共享内存,省去了内存拷贝
生产者&消费者模式对请求任务进行管理
一个IO-thread线程维护连接池中的连接,连接有3种状态:NO_USED、READY、BUSY。
1)NO_USED状态,fd位置空闲,连接位尚未使用
2)READY状态,已经与client端连接连接的fd,等待请求事件
3)BUSY状态,已经收到请求事件,将fd放入任务队列,等待work-thread处理
以单个请求事件为任务单位放入队列
将连接放入任务队列,work-thread处理完这个请求后,该fd继续变为READY放入连接池,等待新的请求到来。因此,一个连接上的请求可能被多个work-thread线程处理。
管理连接池中连接,设置超时时间
某个连接超过一个时间没有事件到来时,服务端主动断开连接;每个连接的nLastActive字段记录上次事件到来orBUSY状态的时刻。
(三)流程
(四)数据结构
PendingPool连接池
SItem连接对象
(五)实现
mask
=> 将连接池中的READY连接加入epoll监听
pool_epoll_wait
=> 等待epoll监听的fd有事件发生
deal_work
=> 依次处理所有有事件的fd
1)listen_fd=>有新的连接请求,accept建立新的socket,并放入连接池
2)其他socket=>有可读请求,从epoll中取消监听&将socket放入任务队列;其他事件,关闭连接
fetch_item
=> 从任务队列取出fd
(六)使用
IO-thread线程
即处理接收请求的线程。其使用epoll监听listen_fd和多个client端fd,并处理epoll监听到的所有事件。
work-thread线程
不断从任务队列取出可读的fd任务,调用对应的函数处理请求,然后将fd继续放入连接池给epoll监听。
(七)问题
epoll_wait的超时时间设置
IO-thread线程经历mask->wait->deal->checktimeout的循环,在deal时会将有请求的连接fd从epoll监听中移除
如果mask时该请求未执行完成,则mask时该fd不加入监听
如果此时1)没有新连接2)其他连接没有新请求,则该IO-thread线程要等待epoll超时时间才能重新监听该fd
而如果该fd的此次执行消耗1ms&下次请求在第2ms,而epoll超时设置为1000ms,则该fd的下次请求要等待999ms才能被epoll监听到
因此,当连接数or请求较少时,client的耗时近似于max(执行耗时,epoll_wait时间),进而,epoll_wait设置为server端请求平均处理时间较为合理
deal中处理可读的连接(有请求)为什么要将fd从epoll监听中移除
如果epoll继续监听该fd,且该fd上又有新的请求,则该fd再次被放入任务队列 => 任务队列中两个fd
可能出现多个线程处理这个连接fd的情况,无法保证顺序性
(一)功能
rpc(远程函数调用)提供client端通过网络调用远程server端的函数的服务。
rpc-server端需要提供较高的吞吐能力,支持较大的并发连接。
(二)设计思路
epoll监听多个连接fd,实现IO复用
1)epoll没有最大并发连接的限制,上限是最大可以打开文件的数目,一般远大于2048
2)epoll效率高,只管活跃的连接,而跟连接总数无关
3)使用共享内存,省去了内存拷贝
生产者&消费者模式对请求任务进行管理
一个IO-thread线程维护连接池中的连接,连接有3种状态:NO_USED、READY、BUSY。
1)NO_USED状态,fd位置空闲,连接位尚未使用
2)READY状态,已经与client端连接连接的fd,等待请求事件
3)BUSY状态,已经收到请求事件,将fd放入任务队列,等待work-thread处理
以单个请求事件为任务单位放入队列
将连接放入任务队列,work-thread处理完这个请求后,该fd继续变为READY放入连接池,等待新的请求到来。因此,一个连接上的请求可能被多个work-thread线程处理。
管理连接池中连接,设置超时时间
某个连接超过一个时间没有事件到来时,服务端主动断开连接;每个连接的nLastActive字段记录上次事件到来orBUSY状态的时刻。
(三)流程
(四)数据结构
PendingPool连接池
序号 | 字段 | 类型 | 含义 |
1 | m_listen_fd | int | 监听客户端请求的fd |
2 | m_aySocket | SItem* | 存放已与client建立的连接对象集合 |
3 | m_socketNum | int | 连接池size |
4 | m_ayEvent | epoll_event* | 记录epoll监听到的活跃事件 |
5 | m_eventNum | int | epoll监听的活跃事件size |
6 | m_ayReady | int* | 任务队列,有可读事件的fd |
7 | m_queueLen | int | 队列长度 |
8 | m_mutex | pthread_mutex_t | 互斥锁,控制出队 |
9 | m_condition | pthread_cond_t | 条件锁,控制入队、出队 |
序号 | 字段 | 类型 | 含义 | 值 |
1 | nLastActive | int | 该连接最后一次活跃时间 | 记录秒数 |
2 | status | int | 连接状态 | 0:未使用;1:已建立连接;2:可读 |
3 | epoll_status | int | 是否加入epoll监听 | 0:未监听;1:已监听 |
4 | processor | shared_ptr<TProtocol>* | thrift协议对象 |
(五)实现
mask
=> 将连接池中的READY连接加入epoll监听
pool_epoll_wait
=> 等待epoll监听的fd有事件发生
deal_work
=> 依次处理所有有事件的fd
1)listen_fd=>有新的连接请求,accept建立新的socket,并放入连接池
2)其他socket=>有可读请求,从epoll中取消监听&将socket放入任务队列;其他事件,关闭连接
fetch_item
=> 从任务队列取出fd
(六)使用
IO-thread线程
即处理接收请求的线程。其使用epoll监听listen_fd和多个client端fd,并处理epoll监听到的所有事件。
work-thread线程
不断从任务队列取出可读的fd任务,调用对应的函数处理请求,然后将fd继续放入连接池给epoll监听。
(七)问题
epoll_wait的超时时间设置
IO-thread线程经历mask->wait->deal->checktimeout的循环,在deal时会将有请求的连接fd从epoll监听中移除
如果mask时该请求未执行完成,则mask时该fd不加入监听
如果此时1)没有新连接2)其他连接没有新请求,则该IO-thread线程要等待epoll超时时间才能重新监听该fd
而如果该fd的此次执行消耗1ms&下次请求在第2ms,而epoll超时设置为1000ms,则该fd的下次请求要等待999ms才能被epoll监听到
因此,当连接数or请求较少时,client的耗时近似于max(执行耗时,epoll_wait时间),进而,epoll_wait设置为server端请求平均处理时间较为合理
deal中处理可读的连接(有请求)为什么要将fd从epoll监听中移除
如果epoll继续监听该fd,且该fd上又有新的请求,则该fd再次被放入任务队列 => 任务队列中两个fd
可能出现多个线程处理这个连接fd的情况,无法保证顺序性
相关文章推荐
- 图像检索服务器编写问题记录——服务器端模型选择+epoll和非阻塞IO
- 常见开源产品epoll网络事件模型分析(附200万QPS实现长连接echo server方案)
- Thrift 多线程阻塞式IO服务模型-TThreadPoolServer
- 基于java.util.logging实现轻量级日志记录库(增加根据当前类class初始化,修复线程池模型(javaEE)下的堆栈轨迹顺序与当前调用方法不一致问题)
- RPC 的概念模型与实现解析(转)
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【四】——实现模型工厂,依赖注入以及格式配置
- socket编程 -- epoll模型服务端/客户端通信的实现
- UtilBox(ub)基础组件 -- epoll_server网络事件模型
- Dubbo源代码实现六:线程池模型与提供者
- IO模型及select、poll、epoll和kqueue的区别
- [置顶] 使用OAuth2 Server PHP实现OAuth2服务----实现token
- Dubbo源代码实现五:RPC中的服务消费方实现
- 三种多路复用IO实现方式:select,poll,epoll的区别
- Golang服务器的网络层实现--总结对比常用epoll模型
- 两个表格实现面向服务构件模型
- Linux下select, poll和epoll IO模型的详解
- 三种主流的Web服务实现方案(REST+SOAP+XML-RPC)简述及比较
- Nginx网络epoll多进程系列:应用层协议实现系列(一)——HTTP服务器之仿nginx多进程和多路IO的实现
- python实现select和epoll模型socket网络编程