從零學Netty(四)Reactor模式(含demo)

Lion Li發表於2020-10-12

介紹

  • Reactor模式是一種為處理併發I/O服務請求,並將請求提交到一個或多個服務處理程式的事件設計模式
  • 當客戶端請求抵達後,服務處理程式使用多路分配策略,由一個非阻塞的執行緒來接收所有請求,然後將請求派發到相關的工作執行緒並進行處理的過程。
  • 和普通函式呼叫不同的是應用程式不是主動的呼叫某個API來完成處理,恰恰相反的是Reactor逆置了事件處理流程
  • 應用程式需提供相應的介面,如果有相應的事件發生,Reactor將主動呼叫應用程式註冊的介面
  • 對於高併發系統經常會使用到Reactor模式,用來替代常用的多執行緒處理方式以節省系統資源並提高系統的吞吐量

對比傳統I/O

  1. 基於I/O複用模型:多個連線共用一個阻塞物件,應用程式只需要在一個阻塞物件等待,無需阻塞等待所有連線
  2. 基於執行緒池複用執行緒資源:不必再為每個連線建立執行緒,將連線完成後的業務處理分配給執行緒處理,一個執行緒可以處理多個連線的業務

Reactor 3種經典實現

  1. 單Reactor單執行緒
  2. 單reactor多執行緒
  3. 主從Reactor多執行緒

Netty主要基於主從Reactor多執行緒模型做了一定的改進,其中主從Reactor多執行緒模型有多個Reactor

在網上找了一個寫的非常好的 實現三種模式的程式碼 所以我就不自己實現了

程式碼地址:https://github.com/chuondev/reactor

如果連線打不開 在文章結尾的連線裡也附帶了程式碼

Reactor 模式中的核心組成

  • Reactor:Reactor在一個單獨的執行緒中執行,負責監聽和分發事件,分發給適當的處理程式來對I/O事件作出反應(例如:公司前臺漂亮小姐姐)
  • Handlers:處理程式執行I/O事件要完成的實際事件(例如:通過前臺小姐姐找到幫你處理實際問題的帥哥)
  • Acceptor:處理客戶端新連線,並分派請求到處理器鏈中

Reactor通過排程適當的處理程式來響應I/O事件,處理程式執行非阻塞操作

單Reactor單執行緒

  • 優點:模型簡單,沒有多執行緒,程式通訊,競爭的問題,全部都在一個執行緒中完成
  • 缺點:效能問題,無法發揮多核CPU的效能,可靠性問題,執行緒意外終止或死迴圈,會導致整個系統不可用
  • 使用場景:客戶端數量有限,業務處理快速,比如Redis在業務處理的事件複雜度O(1)的情況

單reactor多執行緒

  • 優點:充分利用多核CPU的處理能力
  • 缺點:多執行緒資料共享和訪問比較複雜,Reactor處理所有的事件的監聽和響應在單執行緒執行,高併發場景容易出現瓶頸

主從Reactor多執行緒

  • 優點:父執行緒與子執行緒的資料互動簡單職責明確,父執行緒只需要接收新連線,子執行緒完成後續的業務處理
  • 缺點:程式設計複雜度高
  • 例項:Nginx主從Reactor多程式模型,Netty主從多執行緒模型

總結

  • 響應快,不必為單個同步時間所阻塞,可以最大程度的避免複雜的多執行緒及同步問題,並且避免了多執行緒/程式的切換開銷
  • 擴充套件性好,可以通過增加Reactor例項來充分利用CPU資源
  • 複用性好,Reactor模型本身與具體事件處理邏輯無關,具有很高的複用性

 

專案已上傳到gitee

地址: netty-demo

如果幫到您了,請幫忙點個star

相關文章