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