合肥哪個(gè)公司做網(wǎng)站好廣告推廣怎么做最有效
繼續(xù)上一篇Netty文章,這篇文章主要分析Netty對(duì)Channel事件的處理以及空輪詢(xún)Bug的解決
當(dāng)Netty中采用循環(huán)處理事件和提交的任務(wù)時(shí)
由于此時(shí)我在客戶(hù)端建立連接,此時(shí)服務(wù)端沒(méi)有提交任何任務(wù)
此時(shí)select方法讓Selector進(jìn)入無(wú)休止的阻塞等待
此時(shí)selectCnt++進(jìn)行一次計(jì)數(shù),ioRatio用來(lái)設(shè)置處理非事件任務(wù)所占總事件的比例
緊接著進(jìn)入processSelectedKeys方法內(nèi)部,處理連接事件
由于NioEventLoop中維護(hù)了一個(gè)Selector,這里的SelectedKeys是對(duì)原始Selector中的SelectedKeys的一種優(yōu)化,后續(xù)文章會(huì)總結(jié)Netty做的優(yōu)化
這段代碼作用就是獲得到對(duì)應(yīng)事件,然后通過(guò)附件的方式拿到NioServerSocketChannel
緊接著利用NioServerSocketChannel中的unsafe類(lèi)完成消息的寫(xiě)出的讀入
調(diào)用unsafe的read方法后,通過(guò)read方法中的doReadMessages拿到Java ServerSocketChannel建立的SocketChannel
拿到SocketChannel后,創(chuàng)建一個(gè)NioSocketChannel,并創(chuàng)建對(duì)應(yīng)的pipleline,config等等和NioServerSocketChannel一樣。然后把它暫存在一個(gè)List集合buf中
緊接著調(diào)用NioServerSocketChannel的pipleline方法出發(fā)read事件,這里提醒一下pipleline的組成一次是head,logging,acceptor,tail組成
此方法內(nèi)部其實(shí)就是不斷的查找下一個(gè)Handler,調(diào)用Read方法
并且由于一些任務(wù)比較耗時(shí)為了不阻塞鏈接線(xiàn)程可以使用自己設(shè)置線(xiàn)程組
當(dāng)輪到acceptor方法處理時(shí)
注意:這里的childHandler是我們?cè)趕erver端最開(kāi)始的strap代碼時(shí)填入childHandler屬性中的Handler,同時(shí)下方的childGroup就是server端最開(kāi)始的childNioEventLoopGroup
接下來(lái)register方法內(nèi)部就是我們上一篇文章講到的進(jìn)行線(xiàn)程切換,把NioSocketChannel以附件的形式綁定到SocketChannel。由于每個(gè)NioEventLoop都維護(hù)了一個(gè)Selector,同時(shí)把SocketChannel注冊(cè)到(child)NioEventLoopGroup中的NioEventLoop中的Selector接著繼續(xù)循環(huán)監(jiān)聽(tīng)事件處理提交的任務(wù)。分析到這里我們可以理解Netty的基本線(xiàn)程模型了
接下來(lái)連接事件處理完畢,BossGroup該處理普通任務(wù)了
可以看到ioRation是控制所占用時(shí)間的比例的
而selectCnt是為了避免在Linux中導(dǎo)致selector不阻塞從而進(jìn)行計(jì)數(shù),當(dāng)超過(guò)512時(shí)就認(rèn)為出現(xiàn)bug,Netty解決方法就是重新創(chuàng)建一個(gè)Selector,并把原始信息復(fù)制一份。
接下來(lái)我們研究數(shù)據(jù)的發(fā)送和讀寫(xiě)