1、业务处理流程
1.1 主从模型
1.2 Debug跟踪
我们用Netty源码包下面的example来Debug观察一下,包路径io.netty.example.echo
- NioEventLoop#processSelectedKeysOptimized()方式循环处理不同的事件。如下图。
- NioEventLoop#processSelectedKey方法处理一个事件,在该方法中的unsafe.read()这一行打断点(如1.2图), 这是NioEventLoop线程处理读(READ)事件和接受连接(ACCEPT)事件的代码。
- 启动Server,Client发起请求。
1.3 BossGroup处理连接事件,第一次进入是ACCEPT事件
如图, 此时线程是nioEventLoopGroup-2-1,这是BossGroup,就是1.1图中的MainReactor。
unsafe类型AbstractNioMessageChannel.NioMessageUnsafe,这是处理连接事件的,入参ch(channel)类型是NioServerSocketChannel
1.4 跳过这一次循环,进入下一次循环,这次是READ事件
如图, 此时线程是nioEventLoopGroup-3-1,这是workerGroup,即是1.1图中的subReactor
unsafe类型AbstractNioByteChannel.NioByteUnsafe#read,这是处理读事件的,入参ch(channel)类型是NioSocketChannel
1.5 进入unsafe.read
这里是读取数据的逻辑,这个方法主要逻辑前面已经分析了,见Netty源码-业务流程之读事件
这里我们重点关注第4步,pipeline.fireChannelRead(byteBuf); 这里会转到我们自定义的handler处理数据。
pipeline是责任链模式
看一下Debug信息,如下图,pipeline有四个handler,通过双链表连接在一起,HeadContext和TailContext分别表示责任链的头和尾,第三个是我自定义的EchoServerHandler的,真个责任链将会被依次执行。
1.6 进入pipeline.fireCHannelRead,我们来到AbstractChannelHandlerContext#fireChannelRead
findContextInbound找到一个责任节点(Inbound类型)执行,MASK_CHANNEL_READ是channel read掩码。
MASK_ONLY_INBOUND(下图2)表示所有Inbound事件掩码集合,MASK_CHANNEL_READ和MASK_ONLY_INBOUND与运算结果不是0,就表示执行channelRead事件
1.7 最终会进入自定义Handler
最终达到我们自定义的channelRead逻辑,这里可以写我们自己的业务逻辑
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。