前言
我們在使用Netty進行服務端開發的時候,一般來說會定義兩個NioEventLoopGroup線程池,一個"bossGroup"線程池去負責處理客戶端連接,一個"workGroup"線程池去負責處理讀寫操作。那麼,我們為什麼要這麼做呢?這樣做的好處是什麼呢?能不能只使用一個NioEventLoopGroup呢?這就是我們今天要討論的主題——Netty的線程模型
Reactor線程模型
實際上Netty線程模型就是Reactor模式的一個實現,而Reactor模式又是什麼呢?
Reactor模式是基於事件驅動開發的,核心組成部分包括Reactor和線程池,其中Reactor負責監聽和分配事件,線程池負責處理事件,而根據Reactor的數量和線程池的數量,又將Reactor分為三種模型:
- 單線程模型 (單Reactor單線程)
- 多線程模型 (單Reactor多線程)
- 主從多線程模型 (多Reactor多線程)
單線程模型
- Reactor內部通過selector 監控連接事件,收到事件後通過dispatch進行分發,如果是連接建立的事件,則由Acceptor處理,Acceptor通過accept接受連接,並創建一個Handler來處理連接後續的各種事件,如果是讀寫事件,直接調用連接對應的Handler來處理
- Handler完成read->(decode->compute->encode)->send的業務流程
- 這種模型好處是簡單,壞處卻很明顯,當某個Handler阻塞時,會導致其他客戶端的handler和accpetor都得不到執行,無法做到高性能,只適用於業務處理非常快速的場景
多線程模型
- 主線程中,Reactor對象通過selector監控連接事件,收到事件後通過dispatch進行分發,如果是連接建立事件,則由Acceptor處理,Acceptor通過accept接收連接,並創建一個Handler來處理後續事件,而Handler只負責響應事件,不進行業務操作,也就是隻進行read讀取數據和write寫出數據,業務處理交給一個線程池進行處理
- 線程池分配一個線程完成真正的業務處理,然後將響應結果交給主進程的Handler處理,Handler將結果send給client (下面是核心代碼)
單Reactor承當所有事件的監聽和響應,而當我們的服務端遇到大量的客戶端同時進行連接,或者在請求連接時執行一些耗時操作,比如身份認證,權限檢查等,這種瞬時的高併發就容易成為性能瓶頸
主從多線程模型 (最流行)
- 存在多個Reactor, 每個Reactor都有自己的selector選擇器,線程和dispatch
- 主線程中的mainReactor通過自己的selector監控連接建立事件,收到事件後通過Accpetor接收,將新的連接分配給某個子線程
- 子線程中的subReactor將mainReactor分配的連接加入連接隊列中通過自己的selector進行監聽,並創建一個Handler用於處理後續事件
- Handler完成read->業務處理->send的完整業務流程
Netty中的線程模型與Reactor的聯繫
Netty主要靠NioEventLoopGroup線程池來實現具體的線程模型的
單線程模型
單線程模型就是隻指定一個線程執行客戶端連接和讀寫操作,也就是在一個Reactor中完成,對應在Netty中的實現就是將NioEventLoopGroup線程數設置為1,核心代碼是:
它的工作流程大致如下:
上述單線程模型就對應了Reactor的單線程模型
多線程模型
多線程模型就是在一個單Reactor中進行客戶端連接處理,然後業務處理交給線程池,核心代碼如下:
走進group方法可以發現我們平時設置的bossGroup和workerGroup就是使用了同一個group
工作流程如下:
主從多線程模型 (最常使用)
主從多線程模型是有多個Reactor,也就是存在多個selector,所以我們定義一個bossGroup和一個workGroup,核心代碼如下:
工作流程如下:
注意:其實在Netty中,bossGroup線程池最終還是隻會隨機選擇一個線程用於處理客戶端連接,與此同時,NioServerSocetChannel綁定到bossGroup的線程中,NioSocketChannel綁定到workGroup的線程中
小結
以上總結了Reactor的三種模型以及Netty中的對應實現,在Netty中,我們使用的最多的還是主從多線程模型。關於Reactor的學習,最權威的資料應該是Doug Lea大神的Scalable IO in Java,有興趣的同學可以看看
鏈接:https://juejin.im/post/5dac6ef75188252bc1657ead
閱讀更多 Java識堂 的文章