Netty基本介绍,参考 https://juejin.cn/post/7408844429370834954

1、主线程:

Netty源码包的mnetty-example模块随便打开一个实现样例,比如包io.netty.example.echo下的EchoServer,我们从这里的源码开始看

Server启动流程: 创建Selector -》创建ServerSocketChannel -》 初始化ServerSocketChannel -》分配NioEventLoop(请求处理线程)

1.1 在new NioEventLoop(1)打断点,并启动服务

我们先看bossGroup

1.2 创建Selector

 NioEventLoopGroup构造方法中通过SelectorProvider.provide方法调用JDK的SelectorProvider类创建Selector,具体见

Netty源码解析-Channel线程分配和多路复用

1.3 创建和初始化ServerSocketChannel

 通过ServerBootstrap.bind()进入到AbstractBootstrap.initAndRegister方法
 该方法完成三个任务: 
    - 1)创建一个ServerSocketChannel
    - 2)初始化ServerSocketChannel
    - 3)Register:给ServerSocketChannel从BossGroup中选择一个NioEventLoop

1.4 反射工厂创建ServerSocketChannel

通过反射工厂动态创建,具体见Netty源码解析-源码及IO模式

1.5 初始化ServerSocketChannel

1.6 给ServerSocketChannel从bossGroup中选择一个NioEventLoop注册

首先next()方法选择一个NioEventLoop,然后register方法注册到Channel,如下图:

1.6.1 next()选择eventLoop

next方法即使通过一种方式选择一个NioEventLoop注册给Channel,深入next()->EventExecutorChooserFactory.EventExecutorChooser.next() 这个接口有两个实现类,具体机制见Netty源码解析-Channel线程分配和多路复用

1.6.2 register()注册

进入register->SingleThreadEventLoop.register->AbstractChannel.AbstractUnsafe.register

查看断点执行情况,当前是main线程(左下角),第一个分支不会进入,进入第二个分支,会使用eventLoop来执行,在register0中打断点

进入register0方法,我们发现左下角线程变成了,不再是main线程,因为进入了bossGroup 的线程,真正执行register的是doRegister()方法, 下面的safeSetSuccess是异步通知成功

2、BossGroup(MainReactor)线程后续流程

2.1 将ServerSocketChannel注册到选择的NioEventLoop的Selector

进入doRegister,下面就会进入JDK代码,这里做的事情就是将ServerSocketChannel注册到选择的 NioEventLoop的Selector

2.2 绑定地址启动

ServerBootstrap属性设置以后,要绑定地址了。
绑定入口在ServerBootstrap.bind()->doBind(), 回到AbstractBootsrapt.doBind(), 真正执行绑定操作的是doBind0

最终会进入AbstactChannel.bind()->NioServerSocketChannel.doBind(),这里面根据java版本调用的JDK的方法

2.3 注册接受连接事件(OP_ACCEPT)到Selector上

2.3.1 绑定完成后激活

2.3.2 pipeline.fireChannelActive是责任链模式

最终会进入DefaultChannelPipeline.HeadContext#channelActive()

2.3.3 进入readIfIsAutoRead(),来到AbstractChannel#read

又是pipeline.read(),属于类DefaultChannelPipeline,我们进入该类的DefaultChannelPipeline.HeadContext#read()方法


2.3.4 继续进入,最终来到这里AbstractNioChannel#doBeginRead

3.总结

Server启动流程:
先是主线程流程: 创建Selector-> 创建ServerSocketChannel -》 初始化ServerSocketChannel -》分配NioEventLoop-》注册到Channel
接着进入BossGroup线程流程:绑定地址 -》 注册接受链接事件


杜若
67 声望3 粉丝