Netty网络编程-服务端启动问题总结

1、Netty ServerSocktChannel是如何初始化和注册的

img

  1. 获取NioServerSocketChannel的实例,构造方法中还会做以下操作:

    1. 通过SelectorProvider获取ServerSocketChannel。
    2. 设置ServerSocketChannel为非阻塞。
    3. 为此Channel生成内部唯一Id。
    4. 初始化Netty内部Unsafe类实例。
    5. 初始化ChannelPipeline实例。
    6. 初始化ServerSocketChannelConfig实例。
  2. 初始化NioServerSocketChannel的属性

    1. 设置NioServerSocketChannel的Option
    2. 设置NioServerSocketChannel的Attribute,使用的是netty自封装的AttributeMap
    3. 设置NioServerSocketChannel属性ChannelPipeline的ChannelHandler,自定义的Handler
    4. 设置NioServerSocketChannel属性ChannelPipeline的ChannelHandler,添加ServerBootstrapAcceptor
  3. NioServerSocketChannel注册到选择器上

    1. bossGroup中的每个NioEventLoop都有一个selector
    2. 获取bossGroup其中的一个NioEventLoop将此channel注册到选择器

img

img

2、Netty如何处理客户端连接

NioServerSocketChannel是注册到bossGroup中的一个NioEventLoop上的。NioEventLoop会轮训Selector获取事件,根据设置的感兴趣的事件做出相应的处理。例如连接事件。

  1. 轮训注册在其上的 ServerSocketChannel 的 accept 事件(OP_ACCEPT 事件)
  2. 处理 accept 事件,与客户端建立连接,生成一个 NioSocketChannel,并将其注册到WorkerGroup 中某个线程上的 Selector 上
  3. 再去以此循环处理任务队列中的下一个事件

img

img

3、ChannelPipeline中的Handler是何时初始化

NioServerSocketChannel中的ChannelPipeline初始化是在NioServerSocketChannel注册到bossGroup时触发的。

NioSocketChannel的ChannelPipeline初始化是在NioServerSocketChannel注册到childGroup时触发的。

因为首先ChannelPipeline使用的ChannelInitializer添加,所以触发注册事件首先会走到ChannelInitializer.channelRegistered方法,此方法会初始化ChannelPipeline定义的handler,结束后ChannelPipeline将移除自定义的ChannelInitializer实例。

img

img

4、ChannelPipeline中的Handler为什么要New而不能使用同一个实例

不使用@ChannelHandler.Sharable注解,Handler是无法在多个NioSocketChannel中共享的。

img

img

5、Netty如何将accept的连接交给childGroup

初始化NioServerSocketChannel的属性时,设置了NioServerSocketChannel的ServerBootstrapAcceptor,这是个handler,连接入站会处理连接,并分发到childGroup

img

img

posted @ 2022-08-30 10:16  往事随雨  阅读(119)  评论(0编辑  收藏  举报