根據(jù)我們前面分析的,接收到消息后,為了避免在I/O線程里執(zhí)行耗時(shí)的操作,一般都會(huì)使用線程池來(lái)執(zhí)行業(yè)務(wù)處理邏輯.
那是使用Netty提供給我們的方法,傳入一個(gè)線程池還是使用我們自己定義的線程池好呢?
先來(lái)看Netty給我們提供的
ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);
即我們添加handler的時(shí)候可以傳入一個(gè)線程池進(jìn)去
DefaultEventExecutorGroup
它與NioEventLoop之間的區(qū)別又是什么?
NioEventLoop
側(cè)重于處理網(wǎng)絡(luò)I/O相關(guān)的各種事件,例如連接操作,消息讀取和發(fā)送操作
DefaultEventExecutor
側(cè)重于處理業(yè)務(wù)相關(guān)的邏輯,將業(yè)務(wù)的ChannelHandler與具體的DefaultEventExecutor綁定起來(lái).
其次
對(duì)于某個(gè)客戶端連接Channel,只會(huì)注冊(cè)到一個(gè)NioEventLoop線程中,用于處理網(wǎng)絡(luò)I/O操作,業(yè)務(wù)的ChannelHandler指定了運(yùn)行線程池EventLoopGroup之后,創(chuàng)建ChannelHandlerContext上下文時(shí)會(huì)從EventLoopGroup中選擇一個(gè)EventExecutor綁定到該Channel對(duì)應(yīng)的ChannelHandler實(shí)例.
也就是說(shuō)使用netty提供默認(rèn)的,是綁定的.如下圖
使用我們自己定義的線程池
雖然LinkedBlockQueue通過(guò)讀寫鎖來(lái)提升性能,但是當(dāng)業(yè)務(wù)線程數(shù)和寫操作比較多時(shí),鎖競(jìng)爭(zhēng)對(duì)性能的影響還是比較大的骡湖。
如果采用自定義線程池時(shí),優(yōu)化方向就是鎖消除.
可以使用Disruptor或者使用ChannelId與業(yè)務(wù)線程池中的某個(gè)業(yè)務(wù)進(jìn)行綁定