Java NIO 系列文章之 淺析Reactor模式
最近研究 Java IO/">NIO 的時候,常常看到一種 設計模式——Reactor模式,以前沒接觸過這個模式在Netty中也有應用,那麼Reactor模式是什麼?為什麼要使用Reactor模式?在NIO中如何實現Reactor模式?下面將揭開 Reactor的神祕面紗
下面的介紹參考了網上很多相關資料,所以會與網上某些資料有重複的情況,還請見諒
Reactor的介紹
Reactor 是一種和 IO 相關的設計模式,Java中的NIO中天生就對 Reactor模式提供了很好的支援,比較著名的就是Doung Lea 大神在 ofollow,noindex">《Scalable IO in Java》 演示如何使用 NIO 實現Reactor模式
在維基百科上對 Reactor模式定義如下:
The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to the associated request handlers
從上面的描述我們可以得到幾個關鍵點:
- 一種事件驅動模型
- 處理多個輸入
- 採用多路複用將事件分發給相應的Handler處理

在 netty學習系列二:NIO Reactor模型 & Netty執行緒模型 這篇文章談到,Reactor實際上採用了 分而治之 和 事件驅動 的思想:
分而治之: 一個連線裡完整的網路處理過程一般分為 accept,read,decode,process,encode,send這幾步。而Reactor模式將每個步驟對映為 一個Task,服務端執行緒執行的最小邏輯單元不再是一個完整的網路請求,而是 Task,且採用非阻塞方式執行。
事件驅動: 每個Task 對應特定的網路事件,當Task 準備就緒時,Reactor 收到對應的網路事件通知,並將Task 分發給綁定了對應網路事件的 Handler 執行。
總結以上幾個特點,再次說明下 Reactor模式就是 指一個或多個事件輸入同時傳遞給服務處理器(Reactor),服務處理器負責監聽各事件的狀態,當任意一個事件準備就緒時,服務處理器收到該事件通知,並將事件傳送給綁定了該對應網路事件的事件處理器(Handler)執行
Reactor模式也叫做Dispatcher模式,即 I/O多路複用統一監聽事件,收到事件後再分發(Dispatch)給相應的處理執行緒。
模式比較
談到 Reactor模式就會讓我想起觀察者模式,它倆看起來非常相似的,但是觀察者模式主要用於 一對多 的情況,它定義了一個一對多的依賴關係,讓多個觀察者物件監聽一個主題物件,當被觀察者狀態改變時,需要通知相應的觀察者,使這些觀察者能夠自動更新。所以 實際上它們還是有不同的,觀察者模式與單個事件源關聯,而Reactor模式與多個事件源關聯 。
Reactor模式的三種實現
以下的說明參考了Alibaba資深技術專家李運華的極客時間專欄從0開始學架構中對於Reactor的介紹
Reactor模式有三種典型的實現方案:
- 單Reactor單執行緒
- 單Reactor多執行緒
- 主從Reactor多執行緒
在介紹三個方案之前,先來了解下Reactor模式中的幾個角色:
- Reactor : 負責響應事件,將事件分發綁定了該事件的Handler處理
- Handler : 事件處理器,綁定了某類事件,負責執行對應事件的任務對事件進行處理
- Acceptor :Handler的一種,綁定了 connect 事件,當客戶端發起connect請求時,Reactor會將accept事件分發給Acceptor處理
單Reactor單執行緒

PS: 以上的select,accept,read,send是標準I/O複用模型的網路程式設計API,dispatch和"業務處理"是需要完成的操作。
方案的具體步驟如下:
- Reactor物件通過select監控連線事件,收到事件後通過dispatch進行分發
- 如果是連線建立的事件,則交由 Acceptor 通過accept 處理連線請求,然後建立一個 Handler 物件處理連線完成後的後續業務處理
- 如果不是建立連線事件,則 Reactor 會分發呼叫連線對應的 Handler來響應
- Handler 會完成 read -> 業務處理 -> send 的完整業務流程
單Reactor單執行緒的優點:
- 模型簡單,沒有多執行緒,程序通訊,競爭的問題,全部都在一個執行緒中完成
缺點:
- 只有一個程序,無法發揮多核 CPU的效能,只能採取部署多個系統來利用多核CPU,但這樣會帶來運維複雜度
- Handler 在處理某個連線上的業務時,整個程序無法處理其他連線的事件,很容易導致效能瓶頸