服务端启动的时候,创建了两个NioEventLoopGroup,它们实际是两个独立的Reactor线程池。一个用于接收客户端的TCP连接,另一个用于处理I/O相关的读写操作,或者执行系统Task、定时任务Task等。(尽量创建两个NioEventLoopGroup)
- 用于接收客户端请求的线程池职责
- 收客户端TCP连接,初始化Channel参数;
- 将链路状态变更事件通知给ChannelPipeline。
- 处理I/O的线程池的职责
- 异步读取通信对端的数据报,发送读事件到ChannelPipeline;
- 异步发送消息到通信对端,调用ChannelPipeline的消息发送接口;
- 执行系统调用Task;
- 执行定时任务Task,例如链路空闲状态监测定时任务。
主要是:
- 添加任务队列
- 绑定当前线程到EventLoop上
- 调用EventLoop的run方法
执行
1.轮询I/O事件select(wakenUp.getAndSet(false))
- 如果空轮询次数超过一定限制,则新开一个selector,将老的selector上的 selectKey注册到新的 selector 上
- 在轮循selector过程中,会对JDK的空轮循Bug做一个处理。
2.处理事件processSelectedKeys
3.运行任务runAllTasks
- 在EventLoop中,待执行的任务队列分为两种:一种是普通任务队列,一种是定时任务队列。
- 将定时任务取出,聚合到普通任务队列中,再去for循环运行每个Task。