Stories

Detail Return Return

Netty源碼-Server啓動流程 - Stories Detail

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線程流程:綁定地址 -》 註冊接受鏈接事件

Add a new Comments

Some HTML is okay.