Channel
:Socket,對應一個鏈接。java
bind()
、 connect()
、 read()
、 write()
等,就是對 Java 中實現的 Socket 進行必定層次的封裝。EventLoop
:控制流、多線程處理、併發。數組
EventLoopGroup
中包含一個或多個 EventLoop
。EventLoop
在它的生命週期內只和一個 Thread
綁定。EventLoop
處理的 I/O 事件都在它專有的 Thread
上被處理。Channel
在它的生命週期內只註冊於一個 EventLoop
。EventLoop
可能會被分配給一個或多個 Channel
。ChannelFuture
:異步通知。緩存
Future
。可以在以後的某個時間點肯定結果,對 Future
添加 Listener
註冊回調,再操做完成後通知執行相應的回調。ChannelHandler
:在 Channel
上發生事件的處理器。服務器
ChannelInboundHandler
:接收入站事件和數據。ChannelOutboundHandler
:數據出站處理器。ChannelPipeline
: ChannelHandler
鏈的容器。網絡
ChannelPipeline
就是一些 ChannelHandler
的編排順序,每一個 ChannelHandler
接收事件,執行所實現的處理邏輯,完畢後交給下個一個 ChannelHandler
。ChannelPipeline
的編排,在必定次序下調用 ChannelOutboundHandler
。響應的接收服務器發來數據就是入站的,在一個 ChannelPipeline
按順序調用 ChannelInboundHandler
。ChannelPipeline
中從頭部開始按順序調用 ChannnelInboundHandler
。從客戶端發送數據到服務器則是從 ChannelPipeline 的尾部開始執行,直到發送到網絡上。
ChannelHandlerContext
:表明了 ChannelHandler
和 ChannelPipeline
之間的綁定。多線程
Channel
。兩種發送消息的方式:併發
Channel
中:消息從 ChannelPipeline
的尾部開始流動。ChannelHandler
相關聯的 ChannelHandlerContext
對象中: 消息從 ChannelPipeline
的下一個ChannelHandler
開始流動。Channel
都會被分配一個
ChannelPipeline
和
ChannelConfig
。
ChannelConfig
:對應 Channel
的配置設置,支持熱更新。ChannelPipeline
: 持有全部將應用於入站和出站數據以及事件的 ChannelHandler
實例,這些 ChannelHandler
實現了應用程序用於處理狀態變化以及數據處理的邏輯。名稱 | 包 | 描述 |
---|---|---|
NIO | io.netty.channel.socket.nio | 使用 java.nio.channels 包做爲基礎——基於選擇器(select) |
Epoll | io.netty.channel.epoll | 由 JNI 驅動的 epoll() 和非阻塞 IO。這個傳輸支持只有在Linux上可用的多種特性,如 SO_REUSEPORT,比NIO 傳輸更快,並且是徹底非阻塞的 |
OIO | io.netty.channel.socket.oio | 使用 java.net 包做爲基礎——使用阻塞流 |
Local | io.netty.channel.local | 能夠在 VM 內部經過管道進行通訊的本地傳輸 |
Embedded | io.netty.channel.embedded | Embedded 傳輸,容許使用 ChannelHandler 而又不須要一個真正的基於網絡的傳輸。這在測試 ChannelHandler 實現時很是有用 |
Channel
在選擇器(Selector
)上註冊,當 Selector
調用 select()
的時候是阻塞的,直到已經註冊的 Channel
中有相應的事件發生。事件 | 描述 |
---|---|
OP_ACCEPT | 請求在接受新鏈接並建立 Channel 時得到通知 |
OP_CONNECT | 請求在創建一個鏈接時得到通知 |
OP_READ | 請求當數據已經就緒,能夠從 Channel 中讀取時得到通知 |
OP_WRITE | 請求當能夠向 Channel 中寫更多的數據時得到通知。這處理了套接字緩衝區被徹底填滿時的狀況,這種狀況一般發生在數據的發送速度比遠程節點可處理的速度更快的時候 |
處理模型: 異步
Epoll NIO 是基於 Select 的,那麼 Epoll 如其名,則是基於 Linux 的 epoll 。好處不言而喻,提供比舊的 select 和 poll 更好的性能。 對應的則是 EpollEventLoopGroup
和 EpollServerSocketChannel
。socket
OIO 創建在 java.net
包下,不是異步的。可以經過設置 SO_TIMEOUT
來在單線程中處理多個鏈接。函數
Embedded Embedded 提供了能夠將一組 ChannelHandler
做爲幫助器嵌入到其餘的 ChannelHandler
內部。這樣能夠擴展一個 ChannelHandler
的功能,但又不須要修改其內部代碼。
維護了兩個不一樣的索引:readerIndex
和 writerIndex
,一個用於讀取,一個用於寫入。當從 ByteBuf
讀取時,readerIndex
遞增。一樣當從 ByteBuf
寫入時, writerIndex
遞增。 若是 readerIndex
遞增到和 writerIndex
相同的值,那麼到達「可讀取數據的末尾」,這時再進行讀取則會像讀取超出數組末尾的數據同樣,拋出 IndexOutOfBoundsException
。 另外,名稱以 read 或者 write 開頭的 ByteBuf
方法會推動相應的索引值,而以 set 或者 get 開頭的方法則不會(這樣只是在相應的索引值上進行操做)。
在弄清楚 ByteBuf
的使用模式以前,應該理解 Java 中的直接緩衝區和非直接緩衝區:
直接緩衝區:緩衝區創建在物理內存中,能夠提升效率。
非直接緩衝區:緩衝區創建在 JVM 的內存中。
堆緩衝區(backing 模式) ByteBuf
數據存儲在 JVM 的堆空間(非直接緩衝區)中。這種模式也被稱爲「支撐數組(backing array)」,可以在沒有使用池化的的狀況下提供快速的分配和釋放。
直接緩衝區(direct 模式) 經過本地調用分配內存,直接分配的是物理內存。
複合緩衝區 爲多個 ByteBuf
提供一個聚合視圖。
CompositeByteBuf
:可以提供將多個緩衝區(每一個 ByteBuf
能夠是 backing 模式或者 direct 模式)表示爲單個合併緩衝區的虛擬表示。ByteBuf
的索引是從 0 開始到 capacity() - 1。 獲取每一個字節的方法則是:byte getByte(int i);
這樣倒不會改變 readerIndex
和 writerIndex
的值。 固然能夠經過:ByteBuf readerIndex(int index)
和ByteBuf writerIndex(int index)
來手動移動讀取/寫入索引值。discardReadBytes()
方法,能夠丟棄已經被讀過的字節以回收空間。是的,調用discardReadBytes()
能夠確保可寫分段的最大化,可是有可能致使內存複製(可讀字節會移動到緩衝區的開始位置)。一樣的可丟棄字節空間也只是相應的更改了 writerIndex
的值,並不會保證空間中值的擦寫。ByteBuf
的可讀字節分段(CONTENT)存儲了實際數據。任何名稱以 read 或者 skip 開頭的操做都將檢索或者跳過位於當前 readerIndex
的數據,而且將它增長已讀字節數。InputStream
定義了mark(int readlimit)
和reset()
方法,來標記流中指定位置,以及重置。在 ByteBuf
中也有相應的方法來標記和重置 ByteBuf
中的 readerIndex
和 writerIndex
:
markReaderIndex()
markWriterIndex()
resetReaderIndex()
resetWriterIndex()
還有clear()
方法只是重置索引,且不會複製內存。indexOf()
方法。 或者使用ByteProcessor
類。duplicate()
slice()
slice(int , int)
Unpooled.unmodifiableBuffer(...)
order(ByteOrder)
readSlice(int)
以上每一個方法都會返回一個新的ByteBuf
實例,具備本身的讀索引、寫索引和標記索引。可是內部存儲是共享的。因此若是修改了它的內容,也同時修改了其對應的源實例。 若是要深拷貝得到真實副本,使用copy()
或者copy(int ,int)
函數。get()
和set()
操做,從給定的索引值開始,且保持索引值不變。read()
和write()
操做,從給定的索引開始,且會根據以及訪問過的字節數堆索引進行調整。 get()
方法:
set()
方法:
read()
方法:
write()
方法:
ByteBufAllocator
接口 ByteBufAllocator
的方法:
Channel
或者ChannelHandlerContext
獲取到一個ByteBufAllocator
的引用。 Netty提供了兩種ByteBufAllocator
的實現:PooledByteBufAllocator
:池化了ByteBuf
的實例以提升性能而且最大限度的減小內存碎片。UnpooledByteBufAllocator
:不池化ByteBuf
實例,可是每次被調用時會返回一個新的實例。Unpooled
緩衝區 沒法獲取到ByteBufAllocator
的引用時,有一個簡單的Unpooled
工具類,提供靜態的輔助方法來建立未池化的ByteBuf
實例。
ByteBufUtil
類 這個類提供了用於操做ByteBuf
的靜態輔助方法。