一、模型选择
高性能服务器一般用到的是 Reactor 模型,即事件驱动模型。
1、模型一:单 Reactor 单线程模型
只有一个线程会造成性能瓶颈。
适用场景:客户端少,业务处理快速。
2、模型二:单 Reactor 多线程模型
即用线程池处理业务。
降低了代码耦合度,Reactor 线程进行IO处理,业务线程就处理过来的具体业务。
但是单 Reactor 线程包含了所有客户端的事件监控和客户端IO操作,不利于并发场景。
3、模型三:多 Reactor 多线程模型
也叫主从 Reactor 模型。
将连接处理单独取出,单 Reactor 处理连接(主),多 Reactor 处理IO事件监控(从)
充分利用CPU多核资源,合理分配资源。执行流并不是越多越好,过多会增加CPU切换调度成本(所以从Reactor可以放入业务处理,减少线程 )
4、最终模型 one thread one eventloop
二、server模块划分
1、buffer模块
用户态的发送 / 接收缓冲区(针对通信套接字)
意义:防止接收的数据不完整,要先缓存在接收缓冲区。对于给客户端响应的数据,应该在套接字的发送缓冲区可写的情况下发送,在此之前数据只能放在发送缓冲区。
实现功能:向缓冲区添加数据,从缓冲区取数据
2、socket模块
对socket套接字操作进行封装
意义:使使用者操作套接字简单。
实现功能:创建套接字,绑定地址信息,开始监听,通信套接字发起连接,监听套接字接收连接,接收数据,发送数据,关闭套接字。组合调用函数:创建监听套接字,创建通信套接字。
3、channel模块
对每一个描述符进行IO事件监控,回调对应处理函数。
意义:让某个描述符监控事件在用户态更好维护,触发事件后操作流程清晰。
实现功能:描述符是否可读 / 写,监控描述符可读 / 写,解除可读 / 写 / 所有事件监控,对于不同事件回调函数设置。
4、connection模块
对于通信连接进行整体管理,一个连接有任何事件都调用对应回调函数。
意义:不是一个功能模块,是一个管理连接模块。
实现功能:关闭连接,发送数据,协议切换,启动非活跃连接超时释放,取消非活跃连接超时释放,连接建立完成回调,连接有新数据接收成功回调,关闭连接回调,产生事件回调。
5、acceptor模块
对socket和channel模块封装,实现管理监听套接字
意义:获取一个新连接后,要封装成connection对象设置回调。
实现功能:设置新连接回调函数(由最后服务器tcpserver决定)
6、timerqueue模块
超时连接管理,让一个任务在指定时间后被执行。
意义:组件内部对非活跃连接 n 秒后释放。
实现功能:添加定时任务,刷新定时任务(每一次事件处理后都要刷新),取消定时任务。
7、poller模块
事件监控模块,对 epoll 的封装,对任意描述符的事件监控。
意义:对描述符IO事件监控更简单。
实现功能:添加事件监控(channel模块),修改事件监控,移除事件监控。
8、eventloop模块
代表单 Reactor 线程,事件循环模块,对连接事件监控管理模块(epoll模块,timequeue模块),对连接的所有操作放 eventloop 线程保证线程安全。
意义:对于服务器中的所有事件都有 eventloop 模块实现,每一个 connection 连接都会绑定一个 eventloop 模块和线程,因为外界对连接的操作都要放在单独的线程保证安全。
实现功能:将一个任务添加到任务队列线程,定时任务的具体添加刷新和取消。
9、tcpserver模块
对所有子模块的封装,为用户提供方便的搭建服务器接口。
意义:让使用者用简单接口搭建一个tcp服务器。
实现功能:监听连接的管理(有新连接如何处理),通信连接管理(事件触发如何处理),超时连接管理(是否开启非活跃连接),对事件监控管理(启动多少线程和 eventloop),事件回调设置(再设置给 connection 模块)