Netty 核心組件
1. 前言
本節我們主要從整體上了解 Netty 有哪些核心組件,很多同學學習完 Netty 雖然會使用,但是只知道如何自定義 Handler 而已,根本不清楚 Netty 有哪些核心的組件。
本節的主要目的是,從整體上概括 Netty 的核心組件,有助于深入了解 Netty 以及關于 Netty 的面試。
2. 核心組件
Netty 的核心模塊組件主要分為以下:
組件模塊 | 說明 |
---|---|
Boostrap | Bootstrap 其實就是啟動的意思,主要用來配置 Netty 的相關配置,串聯各個組件,針對客戶端。 |
ServerBootstrap | 同上,只是它是針對服務端。 |
線程模型 | 了解 Reactor 線程模型。 |
EventLoopGroup | 是一組 EventLoop 的抽象,可以簡單理解就是線程池,一般分為 BossEventLoopGroup 和 WorkerEventLoopGroup。 |
ChannelFuture | Netty 的所有 IO 操作都是異步的,通過注冊監聽器來監聽執行結果的返回。 |
Channel | Netty 的網絡通信組件,客戶端和服務端建立連接之后會維持一個 Channel。 |
ChannelHandlerContext | 保存 Channel 對于的上下文,同時關聯一個 ChannelHandler 對象。 |
ChannelHandler | 自定義業務 Handler 需要實現它或它的子類,提供了一套生命周期的方法。 |
ChannelPipeline | ChannelPipeline 可認為是一個管道,是管理業務 Handler,通俗理解是保存 ChannelHandler 的 List 集合。 |
ByteBuf | ByteBuf 是一個字節容器,提供了常見 api。Netty 是面向 ByteBuf 來傳輸數據的。 |
編碼和解碼 | Netty 內置了常見編解碼器,我們也可以自定義自己的編解碼器。并且可以把編解碼器封裝成獨立的 Handler,簡化繁瑣的流程。 |
拆包和粘包問題 | 了解為什么會出現拆包和粘包問題,如何去解決它,以及 Netty 內置了常見的拆包器。 |
總結,以上組件(或者知識點)是 Netty 知識體系里面的核心,并且也是面試當中經常問的內容,有的只需要配置一下即可,很少需要我們去管(如:EventLoopGroup);有的需要我們去自定義擴展。
核心組件架構圖:
在真實開發當中,需要我們去解決的問題,主要如下:
- 使用 ChannelPipeline 管理自定義 ChannelHandler;
- 業務實體和 ByteBuf 之間的轉換;
- 借助第三方序列化技術、自定義通信協議規則、反射等,自定義編碼和解碼器,使用通用實體;
- 如何解決拆包和粘包問題,其發生的原因是什么,如果解決。
3. 組件詳解
Netty 的它優勢在于,它是配置化的開發,僅僅靠簡單的配置,背后就能實現很復雜的邏輯。但是通常情況下我們很難去了解其背后的原理。下面我們主要挑選開發當中比較常見的組件進行講解。
3.1 ChannelHandler
ChannelHandler 是一個接口,處理 IO 事件,可以簡單的理解它是一個鏈表當中的一個節點,它的 UML 圖如下所示:
ChannelHandler 架構圖說明:
- ChannelHandler 兩個子接口,分別是 ChannelInboundHandler 和 ChannelOutboundHandler;其中 ChannelInboundHandler 主要用于處理入站的 I/O 事件;ChannelOutboundHandler 用于處理出站的 I/O 事件;
- ChannelInboundHandler 的實現類 ChannelInboundHandlerAdapter 處理入站 I/O 事件;
- ChannelOutboundHandler 的實現類 ChannelOutboundHandlerAdapter 處理出站 I/O 事件;
在開發當中,ChannelInboundHandlerAdapter
是使用最多的,其它很少直接使用。值得注意的是 I/O 入站和出站的執行順序,這個跟 SpringMVC 的攔截器的執行順序一樣。
3.2. ChannelPipeline
ChannelPipeline 是一個比較核心的知識點,它底層設計是采用責任鏈設計模式,主要作用是管理 Handler 雙向鏈表,包括入站和出站,主要是攔截 inboud 和 outbound 事件,然后每個 handler 節點負責處理具體邏輯。
關系梳理:
- 一個客戶端對應一個 Channel;
- 一個 Channel 對應一個 ChannelPipeline;
- 一個 ChannelPipeline 又維護了一個雙向鏈表,其中鏈表的節點是
ChannelHandlerContext
; - 一個
ChannelHandlerContext
則關聯一個ChannelHandler
(自定義 Handler); - ChannelHandler 則是自定義 Handler 的一個頂級抽象接口。
入站和出站的順序:
- 入站: 事件會從鏈表的頭部一直往后執行,
ChannelInboundHandlerAdapter
子類會被觸發; - 出站: 事件會從鏈表的尾部一直往前執行,
ChannelOutboundHandlerAdapter
子類會被觸發。
4. 小結
本節內容,主要讓大家從整體上了解 Netty 有哪些核心的組件構成,每個主要的作用是什么,主要是方便后面章節深入學習。其中,核心掌握 ChannelHandler 和 ChannelPipeline 這兩個組件,平時開發當中涉及比較多的就是這兩個組件。
- 掌握 ChannelHandler 的 UML 架構關系;
- 掌握入站和出站分別繼承 ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapter;
- 掌握 ChannelPipeline 和 ChannelHandler 之間的關系;
- 掌握入站和出站的執行順序。