一、什麼是Channel?
Channel按照其字面意思非常容易理解,那就是”管道”。自來水通遍千家萬戶需要架設管道,暖氣也需要架設管道,同樣,網路通訊也需要架設管道,這個管道就是我們的Socket
。我們發現,自來水管道中流通的是自來水,暖氣管道中流通的是暖氣,那麼Socket
中流通的當屬我們的位元組流了。
說了這麼多,那麼到底什麼是Channel呢?小編理解,Channel就是連線網路Socket和具有read, write, connect, and bind
能力的元件的一條通道。
一個Channel通常擁有下面幾種屬性:
- 1、Channel 本身元件的狀態state,比如說是不是處於開啟
open
狀態,是否處於連線connected
狀態 - 2、Channel 本身將會跟一個
ChannelConfig
物件相關聯,用於對該Channel
進行配置,比如接收緩衝區的大小
- 3、Channel 本身將會跟一個
ChannelPipeline
物件相關聯,用於處理I/O事件events
Netty 中的 Channel
在Java NIO基礎之上封裝了更多的操作。在 Netty 中,所有的I/O操作都是非同步的。這意味著我們不能在呼叫I/O操作之後立即得到I/O操作的結果,因此Netty中提供了一個ChannelFuture
,每次呼叫非同步I/O之後會返回該物件。
在 Netty 中,Channel是具有繼承結構的,我們可以通過呼叫Channel的parent()
方法獲取,parent()
方法的返回取決於該Channel是怎麼建立出來的。比如一個SocketChannel
由一個ServerSocketChannel
接收,因此當呼叫SocketChannel
的parent()
方法時將返回ServerSocketChannel
每次當處理完Channel操作時,我們應該顯式呼叫其close()
和close(ChannelPromise)
對資源進行釋放,這將確保所有資源都以正確的方式釋放掉~
二、Netty中Channel的型別有哪些?分別有什麼作用?
總的來說,不同的協議,不同用途會對應不同型別的Channel
。下面貼出Channel
的介面繼承圖:
- 1、
UnixChannel
:此類Channel只暴露一些在Unix類作業系統上面才會有的操作 - 2、
DatagramChannel
:一個處理UDP/IP
協議的 Channel - 3、
DuplexChannel
:一個擁有兩個端點並能在每個端點獨立關閉的全雙工Channel - 4、
Http2StreamChannel
:支援HTTP/2
協議的 Channel - 5、
SctpChannel
:一個處理SCTP/IP
協議的Channel - 6、
ServerChannel
:一個接收新連線然後建立子Channel的Channel元件,ServerSocketChannel
就是一個很好的例子,ServerSocketChannel
接受連線,然後建立出SocketChannel
三、Netty中Channel和EventLoopGroup、EventLoop之間的關係
一個EventLoop
是一條單純的執行緒,用於處理註冊在其上面的所有I/O事件,也就是說,Channel是需要註冊到EventLoop上面去的,而且一個EventLoop
通常會有多個Channel
註冊,而EventLoopGroup
則是EventLoop
的集合。
四、Netty中EventLoop
等事件執行緒元件繼承圖
小編貼出一張簡單的繼承圖,如下所示:
從圖中其實可以發現,Netty中執行緒模型基本上就是從一個叫EventExecutorGroup
,EventExecutorGroup
繼承了JDK中的ScheduledExecutorService
介面,因此在Netty中我們可以利用它做一些定時任務之類的配置。
- 1、
EventExecutorGroup
:負責通過其next()
方法來建立一系列的EventExecutor
,除此之外,也負責管理其建立的EventExecutor
生命週期並提供全域性關閉方法。 - 2、
EventLoopGroup
是一個特殊的EventExecutorGroup
,主要用於註冊Channel
以便後續在事件迴圈中使用 - 3、
EventExecutor
是一個特殊的EventExecutorGroup
,它提供一些便捷的方法用來判斷一個執行緒是否在一個EnentLoop
中執行 - 4、
MultithreadEventExecutorGroup
顧名思義,就是允許任務在多執行緒中去執行
五、Netty中的Bootstrap
家族
其實Netty中的Bootstrap
啟動類家族不是很龐大,相當於工具類吧!Bootstrap
和ServerBootstrap
屬於上面第二章節說到的ServerChannel
範疇,總共有3個大類,類圖如下:
- 1、
Bootstrap
:用於為客戶端開啟一條通道Channel
,通常bind()
方法用於建立一個基於UDP的無狀態的連結,對於通常的TCP連結,我們則使用其connect()
方法建立 - 2、
ServerBootStrap
:用於在服務端中開啟一個ServerChannel
六、Netty中的ChannelHandler
ChannelHandler
可以用來處理I/O事件或者用於接收I/O操作,並將指標指向ChannelPipeline
中的下一個Handler
。其中ChannelPipeline
為ChannelHandler
提供了一個容器。
ChannelInboundHandler
用於為狀態(open close connect
)的更改設定相應的回撥操作,簡而言之,ChannelInboundHandler
攔截和處理入站事件,ChannelOutboundHandler
攔截和處理出站事件.