業務中 Netty 的使用場景
netty是屬於更底層的東西,主要用於構建高性能、低時延的各種 Java 中間件,例如 MQ、分佈式服務框架、ESB 消息總線等,Netty 主要作爲基礎通信框架爲消息中間件、RPC 框架等產品提供高性能、低時延的通信服務;
例如
阿里分佈式服務框架 Dubbo 的 RPC 框架使用 Dubbo 協議進行節點間通信,Dubbo 協議默認使用 Netty 作爲基礎通信組件,dubbo的服務提供者、服務消費者和性能統計等節點之間使用 Netty 進行異步/同步通信
除了 Dubbo 之外,淘寶的消息中間件 RocketMQ ,消息生產者和消息消費者之間也採用 Netty 進行高性能、異步通信
Netty的組件和設計
- Channel — 通信載體,服務端和客戶端的Socket連接
Channel爲通信載體,負責底層傳輸層的具體事件及消息處理,其封裝底層處理的複雜性,通過統一接口將事件及消息交給成員變量ChannelPipeline處理
- ChannelPipeline — 消息的管道
ChannelPipeline爲消息的管道,一個Channel對應唯一ChannelPipeline,一個ChannelPipeline中包含多個ChannelHandlerContext,各個ChannelHandlerContext以鏈表的形式構成消息處理的責任鏈
(1)ChannelPipeline 提供了 ChannelHandlerContext 鏈的容器,ChannelPipeline 維護了一個ChannelHandlerContext 類型的head和一個tail,進而形成一個ChannelHandlerContext 鏈
(2)每一個新創建的 Channel 都將會被分配一個新的 ChannelPipeline,Channel 既不能附加另外一個 ChannelPipeline,也不能分離其當前的
- ChannelHandlerContext
ChannelHandlerContext是ChannelPipeline的上下文,一個ChannelPipeline中包含多個ChannelHandlerContext,各個ChannelHandlerContext以鏈表的形式構成消息處理的責任鏈
ChannelHandlerContext維護了一個成員變量ChannelHandler
在Netty中,有兩種發送消息的方式。你可以直接寫到Channel中,也可以寫到和ChannelHandler 相關聯的 ChannelHandlerContext 對象中
前一種方式會讓消息從 ChannelPipeline 的尾端開始流動,而後者會讓消息從當前所關聯的 ChannelHandler 開始,並且只會傳播給責任鏈上的下一個能夠處理該事件的 ChannelHandler
- ChannelHandler 具體的消息處理類
(1)應用程序的業務邏輯通常定義在一個或者多個 ChannelInboundHandler 中
(2)ChannelInboundHandler從頭部開始處理,ChannelOutboundHandler從尾部開始處理
幾個channel相關類之間的關係:
ChannelPipeline 並不對消息做處理,其只是轉發給 ChannelHandlerContext 處理,而ChannelHandlerContext 又交給具體的ChannelHandler處理,並將處理後的消息沿着鏈表轉發給下一個ChannelHandlerContext
channel中的事件傳播
- ChannelConfig – Channel 的配置設置
每個 Channel 都將會被分配一個 ChannelPipeline 和 ChannelConfig。 ChannelConfig 包含了該 Channel 的所有配置設置,並且支持熱更新
NIO處理channel狀態
selector選擇器輪詢處理所有的channel的狀態變化通知
EventLoop — 控制流、多線程處理、併發
執行邏輯
EventLoopGroup可以被設置爲bossGroup和workerGroup, bossGroup 用於接受 Tcp 請求,他會將請求交給 workerGroup ,workerGroup 會獲取到真正的連接,然後和連接進行通信,比如讀寫解碼編碼等操作
EventLoop,EventLoopGroup,Channel之間的關係:
流程:
創建channel – 》 將channel註冊到eventLoop上 – 》整個生命週期都使用EventLoop處理I/O事件
一個eventLoopGroup是一個線程組,一個eventLoop是一個線程,所有的eventLoop處理的I/O事件都將在其專有的thread上處理,從而保證線程安全,因此thread:eventLoop = 1:1
一個eventLoop可以被分配多個channel ,所以eventLoop:channel = 1:n
netty流程:
handler和childHandler
handler處理服務端的邏輯,比如說一個handler添加了,一個channel連接了
childHandler對於連接的處理,例如接收緩衝區,發送緩衝區,對tcp的設置
預置的 ChannelHandler 和編解碼器
SslHandler
在大多數情況下,SslHandler將是ChannelPipeline中的第一個OutputChannelHandler。 這確保了只有在所有其他的 OutputChannelHandler 將它們的邏輯應用到數據之後,纔會進行加密
HTTP 解碼器、編碼器和編解碼器
HttpRequestEncoder
HttpRequestDecoder
HttpObjectAggregator——聚合 HTTP 消息
HttpContentCompressor && HttpContentDecompressor——HTTP 壓縮和解壓