Netty高性能架構之Reactor模式

  在討論Netty的架構模式之前,我們先來介紹下Reactor模式,因爲Netty的架構模式是在此基礎上演變而來的

Reactor模式介紹

1. 線程模型基本介紹

  不同的線程模式,對程序的性能有很大影響,爲了搞清Netty 線程模式,我們來系統的講解下 各個線程模式, 最後看看Netty 線程模型有什麼優越性.

  目前存在的線程模型有:傳統阻塞 I/O 服務模型 Reactor 模式
根據 Reactor 的數量和處理資源池線程的數量不同,有 3 種典型的實現

  1. 單 Reactor 單線程;
  2. 單 Reactor 多線程;
  3. 主從 Reactor 多線程
    Netty 線程模式(Netty 主要基於主從 Reactor 多線程模型做了一定的改進,其中主從 Reactor 多線程模型有多個 Reactor)

2. 傳統阻塞I/O服務模型

2.1 工作原理

在這裏插入圖片描述

說明:

黃色的框表示對象, 藍色的框表示線程,白色的框表示方法(API)

2.2 模型特點

  採用阻塞IO模式獲取輸入的數據,每個連接都需要獨立的線程完成數據的輸入,業務處理,數據返回

2.3 問題分析

  當併發數很大,就會創建大量的線程,佔用很大系統資源,連接創建後,如果當前線程暫時沒有數據可讀,該線程會阻塞在read 操作,造成線程資源浪費

3. Reactor模式

  針對傳統阻塞 I/O 服務模型的 2 個缺點,解決方案

  1. 基於 I/O 複用模型:多個連接共用一個阻塞對象,應用程序只需要在一個阻塞對象等待,無需阻塞等待所有連接。當某個連接有新的數據可以處理時,操作系統通知應用程序,線程從阻塞狀態返回,開始進行業務處理Reactor 對應的叫法: 1. 反應器模式 2. 分發者模式(Dispatcher) 3. 通知者模式(notifier)

  2. 基於線程池複用線程資源:不必再爲每個連接創建線程,將連接完成後的業務處理任務分配給線程進行處理,一個線程可以處理多個連接的業務。

在這裏插入圖片描述

I/O 複用結合線程池,就是 Reactor 模式基本設計思想,如圖:
在這裏插入圖片描述

說明:

  1. Reactor 模式,通過一個或多個輸入同時傳遞給服務處理器的模式(基於事件驅動)
  2. 服務器端程序處理傳入的多個請求,並將它們同步分派到相應的處理線程, 因此Reactor模式也叫 Dispatcher模式
  3. Reactor 模式使用IO複用監聽事件, 收到事件後,分發給某個線程(進程), 這點就是網絡服務器高併發處理關鍵

Reactor 模式中 核心組成:

  1. Reactor:Reactor 在一個單獨的線程中運行,負責監聽和分發事件,分發給適當的處理程序來對 IO 事件做出反應。 它就像公司的電話接線員,它接聽來自客戶的電話並將線路轉移到適當的聯繫人;

  2. Handlers:處理程序執行 I/O 事件要完成的實際事件,類似於客戶想要與之交談的公司中的實際官員。Reactor 通過調度適當的處理程序來響應 I/O 事件,處理程序執行非阻塞操作。

3.1 單Reactor單線程

3.1.1 方案說明

在這裏插入圖片描述

  1. Select 是前面 I/O 複用模型介紹的標準網絡編程 API,可以實現應用程序通過一個阻塞對象監聽多路連接請求
  2. Reactor 對象通過 Select 監控客戶端請求事件,收到事件後通過 Dispatch 進行分發
  3. 如果是建立連接請求事件,則由 Acceptor 通過 Accept 處理連接請求,然後創建一個 Handler 對象處理連接完成後的後續業務處理
  4. 如果不是建立連接事件,則 Reactor 會分發調用連接對應的 Handler 來響應
  5. Handler 會完成 Read→業務處理→Send 的完整業務流程

結合實例:服務器端用一個線程通過多路複用搞定所有的 IO 操作(包括連接,讀、寫等),編碼簡單,清晰明瞭,但是如果客戶端連接數量較多,將無法支撐,前面的 NIO 案例就屬於這種模型。

3.1.2 優缺點分析

優點:模型簡單,沒有多線程、進程通信、競爭的問題,全部都在一個線程中完成
缺點:性能問題,只有一個線程,無法完全發揮多核 CPU 的性能。Handler 在處理某個連接上的業務時,整個進程無法處理其他連接事件,很容易導致性能瓶頸
缺點:可靠性問題,線程意外終止,或者進入死循環,會導致整個系統通信模塊不可用,不能接收和處理外部消息,造成節點故障

使用場景:客戶端的數量有限,業務處理非常快速,比如 Redis在業務處理的時間複雜度 O(1) 的情況

3.2 單Reactor多線程

3.2.1 原理圖

在這裏插入圖片描述

  1. Reactor 對象通過select 監控客戶端請求事件, 收到事件後,通過dispatch進行分發
  2. 如果建立連接請求, 則由Acceptor 通過accept 處理連接請求, 然後創建一個Handler對象處理完成連接後的各種事件
  3. 如果不是連接請求,則由reactor分發調用連接對應的handler 來處理
  4. handler 只負責響應事件,不做具體的業務處理, 通過read 讀取數據後,會分發給後面的worker線程池的某個線程處理業務
  5. worker 線程池會分配獨立線程完成真正的業務,並將結果返回給handler
  6. handler收到響應後,通過send 將結果返回給client

3.2.2 優缺點分析

優點:可以充分的利用多核cpu 的處理能力
缺點:多線程數據共享和訪問比較複雜, reactor 處理所有的事件的監聽和響應,在單線程運行, 在高併發場景容易出現性能瓶頸.

3.3 主從Reactor多線程

  針對單 Reactor 多線程模型中,Reactor 在單線程中運行,高併發場景下容易成爲性能瓶頸,可以讓 Reactor 在多線程中運行

3.3.1 原理分析

在這裏插入圖片描述

  1. Reactor主線程 MainReactor 對象通過select 監聽連接事件, 收到事件後,通過Acceptor 處理連接事件
  2. 當 Acceptor 處理連接事件後,MainReactor 將連接分配給SubReactor
  3. subreactor 將連接加入到連接隊列進行監聽,並創建handler進行各種事件處理
  4. 當有新事件發生時, subreactor 就會調用對應的handler處理
  5. handler 通過read 讀取數據,分發給後面的worker 線程處理
  6. worker 線程池分配獨立的worker 線程進行業務處理,並返回結果
  7. handler 收到響應的結果後,再通過send 將結果返回給client
  8. Reactor 主線程可以對應多個Reactor 子線程, 即MainRecator 可以關聯多個SubReactor

在這裏插入圖片描述

3.3.2 優缺點說明

優點:父線程與子線程的數據交互簡單職責明確,父線程只需要接收新連接,子線程完成後續的業務處理。
優點:父線程與子線程的數據交互簡單,Reactor 主線程只需要把新連接傳給子線程,子線程無需返回數據。
缺點:編程複雜度較高

結合實例:這種模型在許多項目中廣泛使用,包括 Nginx 主從 Reactor 多進程模型, Memcached 主從多線程,Netty 主從多線程模型的支持

3.4 Reactor小結

3 種模式用生活案例來理解

  1. 單 Reactor 單線程,前臺接待員和服務員是同一個人,全程爲顧客服
  2. 單 Reactor 多線程,1 個前臺接待員,多個服務員,接待員只負責接待
  3. 主從 Reactor 多線程,多個前臺接待員,多個服務生

Reactor 模式具有如下的優點:

  1. 響應快,不必爲單個同步時間所阻塞,雖然 Reactor 本身依然是同步的
  2. 可以最大程度的避免複雜的多線程及同步問題,並且避免了多線程/進程的切換開銷
  3. 擴展性好,可以方便的通過增加 Reactor 實例個數來充分利用 CPU 資源
  4. 複用性好,Reactor 模型本身與具體事件處理邏輯無關,具有很高的複用性
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章