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