以主从Reactor为例,Server在启动的时候,会创建Boss和Worker两个EventLoopGroup,这两个group会作为参数传入到ServerBootstrap的group方法中。
AbsttractBootstrap.bind->绑定端口
AbsttractBootstrap.initAndRegister->初始化channel并注册channel
MultithreadEventLoopGroup.register
SingleThreadEventLoop.register
AbstractChannel.register
SingleThreadEventExecutor.execute
SingleThreadEventExecutor.startThread->这个只会在初始化的时候start一次,因为inEventLoop是false。
SingleThreadEventExecutor.doStartThread
ThreadPerTaskExecutor.execute->4.1.X新加入的方法,将用工厂创建线程并启动执行任务的动作封装了起来,也是真正启动Boss线程的地方,之前都是用户线程。
SingleThreadEventExecutor.this.run
NioEventLoop.run->这里是一个死循环,在ratio不是100的时候,会一直跑任务,主要工作有两个:
NioEventLoop.processSelectedKeys 和 SingleThreadEventExecutor.runAllTasks。
下面先说下SingleThreadEventExecutor.runAllTasks。
无论你在构造EventLoopGroup的时候的入参传入的nThreads是多少,真正创建并启动的Boss线程的个数只和bind的端口数有关。如果server只绑定了一个端口(大部分服务器都是只绑定一个端口),那么及时nThreads>1,那么也只会启动一个Boss线程。
因为这个线程的启动是bind动作的附属操作(bind中的register0),所以和bind的次数相关。
接上面,在ThreadPerTaskExecutor.execute执行,也就是真正启动线程之后,执行取任务操作:
SingleThreadEventExecutor.runAllTasks->这里会取两种不同的task,定时任务也会被添加到taskQueue中
SingleThreadEventExecutor.fetchFromScheduledTaskQueue->最开始定时的task没有
SingleThreadEventExecutor.pollTask->普通task有一个元素,就是上面说的启动线程之前添加进去的register的task
AbstractEventExecutor.safeExecute->poll出来的任务都在这里执行
在Boss线程组启动之前,SingleThreadEventExecutor.execute中会先添加一个task,该task是注册channel,这是第一个添加进去的任务register0:
AbstractChannel$AbstractUnsafe.register0
该任务又会衍生出两个其他任务,这两个衍生任务在register0方法中。
1) 第一个衍生任务
invokeHandlerAddedIfNeeded:686, DefaultChannelPipeline
callHandlerAddedForAllHandlers:1161, DefaultChannelPipeline
execute:1487, DefaultChannelPipeline$PendingHandlerAddedTask
handlerAdded:107, ChannelInitializer->在上面添加完handler之后,初始化channel
initChannel:178, ServerBootstrap$1->向pipeline中添加ChannelHandler
execute:773, SingleThreadEventExecutor->添加的动作在这个execute中执行
SingleThreadEventExecutor->addTask->这里,该衍生任务添加到taskQueue中
所以,到此,又回到了上面提到的那个流程,只是这次在execute方法中,inEventLoop是true,不用再启动boss线程了。
2) 第二个衍生任务
safeSetSuccess:978, AbstractChannel$AbstractUnsafe
notifyListenersNow:485, DefaultPromise
notifyListener0:511, DefaultPromise
operationComplete:296, AbstractBootstrap$1
doBind0:362, AbstractBootstrap
execute:773, SingleThreadEventExecutor->这里又回到了熟悉的流程里
3) 第二个衍生任务又会衍生一个任务
接上面:
bind:254, AbstractChannel
bind:1019, DefaultChannelPipeline
bind:486, AbstractChannelHandlerContext
invokeLater:1012, AbstractChannel$AbstractUnsafe
第一次,调用线程是用户线程,是bind->register的时候,register:479, AbstractChannel$AbstractUnsafe,会启动boss线程。
第二次,调用线程是Boss线程,register0:510, AbstractChannel$AbstractUnsafe,invokeHandlerAddedIfNeeded:686, DefaultChannelPipeline。
第三次,调用线程是Boss线程,register0:512, AbstractChannel$AbstractUnsafe,safeSetSuccess:978, AbstractChannel$AbstractUnsafe。
第四次,调用线程是Boss线程,bind:486, AbstractChannelHandlerContext,invokeLater:1012, AbstractChannel$AbstractUnsafe
第一次,任务是register0
第二次,register0的衍生操作,pipeline.addLast,添加ChannelHandler
第三次,register0的衍生操作,doBind0中的Channel.bind操作
第四次,doBind0的衍生操作,bind:566, AbstractChannel$AbstractUnsafe,invokeLater:1012, AbstractChannel$AbstractUnsafe,task任务是pipeline.fireChannelActive()
后面会详解一下pipeline.fireChannelActive注册连接事件这块。