1. 程式人生 > >Netty新連接接入

Netty新連接接入

... while循環 abs 外部命令 http javac java oev mina

問題

1.Netty是在哪裏檢測有新連接接入的?

答:boss線程的第一個過程輪訓處Accept事件,然後boss線程第二個過程通過jdk底層的channel的accept方法創建該連接。

2.新連接是怎樣註冊到NioEventLoop線程的?

答:新連接NioEventLoop的分配和selector註冊可以回答。boss線程調用chooser的next方法,拿到一個NioEventLoop,然後將這條連接註冊到NioEventLoop的selector上面。

Netty新連接接入處理邏輯

(1)檢測新連接:新連接通過服務端Channel綁定的Selector輪詢出Accept事件

(2)創建NioSocketChannel:基於jdkNio的channle創建出一個netty的NioSocketChannel,也就是客戶端Channel

(3)分配線程及註冊selector:netty給客戶端Channel分配一個NioEventLoop,並且把這條Channel註冊到該NioEventLoop對應的selector上,至此這條Channel後續的讀寫都由此NioEventLoop進行管理

(4)向selector註冊讀事件:註冊的過程和服務端啟動註冊事件復用同一段邏輯。

(1)檢測新連接

processSelectedKey(key,channel)[入口]:添加斷點

  NioMessageUnsafe.read()

    doReadMessages()[while循環]

      javaChannel().accept()

  • 運行Server.java的main函數,啟動服務端
  • 在terminal中輸入 telnet 127.0.0.1 8888(如果出現telnet不是內部或外部命令...則在控制面板-程序-啟用或關閉Windows功能,勾選Telnet客戶端)
  • 一步一步斷點調試

(2)創建NioSocketChannel

new NioSocketChannel(parent,ch)[入口]

  AbstractNioByteChannel(p,ch,op-read)

    configureBlocking(false)&save op

    create id,unsafe,pipeline

  new NioSocketChannelConfig()

    setTcpNoDelay(true)禁止Nagle算法,小的數據包會發出去,降低延遲

(3)分配線程及註冊selector

服務端Channel的pipeline構成

Head—>ServerBootstrapAcceptor—>Tail

其中ServerBootstrapAcceptor做以下事情:

  • 添加childHandler
  • 設置options和attrs
  • 選擇NioEventLoop並註冊selector

(4)向selector註冊讀事件

Netty中Channel的分類

  • NioServerSocketChannel:服務端Channel
  • NioSocketChannel:客戶端Channel
  • Unsafe

技術分享圖片

服務端Channel和客戶端Channel的不同點:

(a) 客戶端Channel(AbstractNioByteChannel)向AbstractNioChannel註冊一個讀事件

  服務端Channel(AbstractNioMessageChannel)向AbstractNioChannel註冊一個accept事件

  服務端Channel和客戶端Channel共同的部分都由AbstractNioChannel實現

(b) 這兩種Channel底層對應的Unsafe不同

  客戶端Channel對應NioByteUnsafe:讀取IO數據

  服務端Channel對應NioMessageUnsafe:讀一條連接

技術分享圖片

Netty新連接接入