Netty业务处理线程池的选择

根据我们前面分析的,接收到消息后,为了避免在I/O线程里执行耗时的操作,一般都会使用线程池来执行业务处理逻辑.

那是使用Netty提供给我们的方法,传入一个线程池还是使用我们自己定义的线程池好呢?

先来看Netty给我们提供的

ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);

即我们添加handler的时候可以传入一个线程池进去
DefaultEventExecutorGroup

它与NioEventLoop之间的区别又是什么?

NioEventLoop

侧重于处理网络I/O相关的各种事件,例如连接操作,消息读取和发送操作

DefaultEventExecutor

侧重于处理业务相关的逻辑,将业务的ChannelHandler与具体的DefaultEventExecutor绑定起来.

15854876-0271285caef123af.png
EventLoop继承图.png

其次

对于某个客户端连接Channel,只会注册到一个NioEventLoop线程中,用于处理网络I/O操作,业务的ChannelHandler指定了运行线程池EventLoopGroup之后,创建ChannelHandlerContext上下文时会从EventLoopGroup中选择一个EventExecutor绑定到该Channel对应的ChannelHandler实例.

也就是说使用netty提供默认的,是绑定的.如下图

15854876-ca935039f64c52d5.png
业务绑定EventExecutor模型的线程模型.png

使用我们自己定义的线程池

15854876-9ac1c98909ed07b8.png
业务自定义线程池模型的线程模型.png

虽然LinkedBlockQueue通过读写锁来提升性能,但是当业务线程数和写操作比较多时,锁竞争对性能的影响还是比较大的。

如果采用自定义线程池时,优化方向就是锁消除.
可以使用Disruptor或者使用ChannelId与业务线程池中的某个业务进行绑定

猜你喜欢

转载自blog.csdn.net/weixin_33788244/article/details/87165526