Netty源码 服务端的启动
最近一直在看netty,看完之后就想做點(diǎn)筆記??墒菍?shí)在是太忙了,擠了還要幾個(gè)晚上終于擠出來(lái)了
?
上圖是服務(wù)端的實(shí)例代碼。大致的流程先梳理一遍。
首先會(huì)執(zhí)行?用于創(chuàng)建兩個(gè)線程組,boosGroup用于接受外部連接,對(duì)?SelectionKey.OP_ACCEPT 感興趣
,workGroup用于處理io操作,內(nèi)部,每當(dāng)有新連接進(jìn)來(lái)的時(shí)候boosGroup 都會(huì)把連接封裝成一個(gè)channel 交給workGroup 去處理。
?
我們?cè)倏?NioEventLoopGroup 的構(gòu)造方法,一直點(diǎn)進(jìn)去,實(shí)際上調(diào)用的?MultithreadEventExecutorGroup?
?
?可以看到 這兩行代碼實(shí)際就是創(chuàng)建兩個(gè)包含?NioEventLoop 對(duì)象的數(shù)組。NioEventLoop對(duì)象我們后面介紹。
ServerBootstrap 是一個(gè)輔助類,主要用于設(shè)置各種配置參數(shù),
.group(bossGroup, workerGroup)?
就是上面我們創(chuàng)建的兩個(gè)線程組,bossGroup的作用就是不斷地accept到新的連接,將新的連接丟給workerGroup來(lái)處理
.channel(NioServerSocketChannel.class)?
表示服務(wù)端啟動(dòng)的是nio相關(guān)的channel,channel在netty里面是一大核心概念,可以理解為一條channel就是一個(gè)連接或者一個(gè)服務(wù)端bind動(dòng)做
.childHandler(new ChannelInitializer<SocketChannel>)表示一條新的連接進(jìn)來(lái)之后,該怎么處理
上面的幾行代碼都是做相應(yīng)配置。
真正的關(guān)鍵在于bind方法
我們一路點(diǎn)擊進(jìn)去。這個(gè)干了三件事 初始化,注冊(cè),綁定端口。
我們先看?initAndRegister
總共三步,創(chuàng)建channel,初始化,注冊(cè)。
1.創(chuàng)建 反射調(diào)用,這里的clazz是在中設(shè)置的,所以這里創(chuàng)建出的是NioServerSocketChannel
2.初始化?
?
初始化只做了兩件事
p.addLast()向serverChannel的流水線處理器中加入了一個(gè)?ServerBootstrapAcceptor,從名字上就可以看出來(lái),這是一個(gè)接入器,專門接受新請(qǐng)求,把新的請(qǐng)求扔給某個(gè)事件循環(huán)器
3.注冊(cè)
將該條channel綁定到一個(gè)selector上去,一個(gè)selector被一個(gè)reactor線程使用,后續(xù)該channel的事件輪詢,以及事件處理,異步task執(zhí)行都是由此reactor線程來(lái)負(fù)責(zé)
?
現(xiàn)在我們的channel已經(jīng)和reactor線程綁定在一起了,現(xiàn)在就剩下最后一步了,完成端口的綁定。
netty通過(guò)異步線程的方式完成端口綁定,這段代碼比較難找,最終會(huì)來(lái)到?io.netty.channel.DefaultChannelPipeline.HeadContext#bind
?
?最終調(diào)到了jdk里面的bind方法,這行代碼過(guò)后,正常情況下,就真正進(jìn)行了端口的綁定。
?
轉(zhuǎn)載于:https://www.cnblogs.com/xmzJava/p/9425440.html
總結(jié)
以上是生活随笔為你收集整理的Netty源码 服务端的启动的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [CF587F]Duff is Mad[
- 下一篇: git在实际开发中的应用