Netty的事件循环机制跟–javascipt的单线程模型相同。
一个EventLoopGroup具有一个或多个EventLoop,EventLoop作为一个Thread给Channel执行工作。当创建一个Channel,Netty通过一个单独的EventLoop实例来注册该Channel,这就是你的应用程序不需要同步Netty的I/O操作;所有Channel的I/0操作始终用相同的线程来执行。
netty的串行处理策略
Netty的处理策略是每当有一个新的客户端接入,则NioEventLoop 线程组中顺序获取一个可用的NioEventLoop,当到达数组上限之后,重新返回到0,通过这种方式,可以基本保证各个NioEventLoop的负载均衡。一个客户端连接只注册到一个NioEventLoop上,这样就避免了多个IO线程去并发操作它。
netty串行处理的优势
- 降低用户开发难度,提升处理性能
- 避免上下午切换和并发保护带来的额外性能
netty编程开发最佳实践
时间可控的简单业务直接在IO线程上处理
如果业务非常简单,执行时间非常短,不需要与外部网元交互、访问数据库和磁盘,不需要等待其它资源,则建议直接在业务ChannelHandler中执行。
时间不可控业务建议投递到后端业务线程池统一处理
对于此类业务,不建议在ChannelHandler中启动线程或者线程池处理,建议将不同的业务统一封装成task,统一投递到后端业务线程池中进行统一处理。
static final EventExecutorGroup group = new DefaultEventExecutorGroup(16);
...
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("decoder", new MyProtocolDecoder());
pipeline.addLast("encoder", new MyProtocolEncoder());
//耗时任务在独立的线程池中进行
pipeline.addLast(group, "handler", new MyBusinessLogicHandler());