亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

首頁 慕課教程 Netty 教程 Netty 教程 Netty Reactor 模型之主從多線程模型

Netty Reactor 模型之主從多線程模型

1. 前言

通過上節的分析,我們知道單 Reactor 多線程模型它的性能瓶頸在于單個 Reactor,本節主要講解如何進行優化單個 Reactor 帶來的性能瓶頸問題。

2. 單 Reactor 性能瓶頸

單 Reactor 主要存在的性能瓶頸如下:

  1. 壓力問題: 客戶端數量比較多的情況,單個 Reactor 負責監聽和轉發,那么 Reactor 壓力非常的大;
  2. 單點故障問題: 如果 Reactor 發生故障,則即使后面的 Handler 和 Worker 正常工作,但是整個應用程序無法正常對外提供服務。

3. 如何進行優化

思考:如何解決單 Reactor 性能問題呢?

  1. 以 Tomcat 作為案例來進行分析:
    1.1 問題: 我們平時把項目打包成 war 部署到單個 Tomcat 來進行運行,在并發量很小的情況下是正常運行的,但是一旦并發量達到 1k 以上,單個 Tomcat 就會很吃力了,那怎么辦呢?
    1.2 解決: 很簡單,只需要在 Tomcat 前面加 Nginx 做負載轉發,這樣的話,多個 Tomcat 同時對外提供服務,不但整體的性能得到提高,即使其中一個 Tomcat 宕機,但是整個 Tomcat 集群還是能正常對外提供服務。
  2. 生活中飯館的案例進行說明:
    還是以飯館經營模型說明,方便大家更好的理解。
    2.1 一個飯館只有一個老板,老板即兼職服務員和廚師的工作,整體效率很低,這就是單 Reactor 單線程模型;
    2.2 一個負責迎接客戶、點菜、上菜的服務員(Reactor 線程),幾個廚師負責炒菜(Worker 線程),廚師輕松了,但是服務員依然忙不過來,這就是單 Reactor 多線程模型;
    2.3 一個負責迎接在門口迎接小妹妹(好比:Reactor 主線程),幾個專門負責點菜和上菜的服務員(好比:Reactor 從線程),幾個負責超出廚師(Worker 線程),那么每個崗位都會很輕松,并且還能服務更多的客戶進行就餐,這就是主從 Reactor 多線程模型。

其實,Reactor 模型也是類似道理,哪個環節性能存在瓶頸,那么將其功能再細分,并且增加執行數量(集群)即可。

4. 主從多線程模型

圖片描述

架構圖分析:

  1. 主要分為三個模塊,分別為 Reactor 主線程、Reactor 子線程、Worker 線程池。其中 Reactor 主線程可以對應多個 Reactor 子線程,也就是說,一個 MainReactor 對應多個 SubReactor;
  2. Reactor 主線程的 MainReactor 對象通過 select 監聽客戶端連接事件,收到事件之后,通過 Acceptor 處理連接事件;
  3. 當 Acceptor 處理連接事件之后,MainReactor 將連接事件分配給 Reactor 子線程的 SubReactor 進行處理;
  4. SubReactor 將連接加入到連接隊列進行監聽,并且創建 Handler 處理對應的事件。一旦有新的事件(非連接)則分配給 Handler 進行處理;
  5. Handler 通過 read () 方法讀取數據,并且分發給 Worker 線程池去做業務處理;
  6. Worker 線程池分配線程去處理業務,處理完成之后把結果返回給 Handler;
  7. Handler 收到 Worker 線程返回的結果之后,再通過 send () 方法返回給客戶端。

方案的優點:

  1. 責任明確,單一功能拆分的更細,Reactor 主線程負責接收請求,不負責處理請求;Reactor 子線程負責處理請求。并發量很高的情況,可以減輕單個 Reactor 的壓力,并且提高處理速度;
  2. Reactor 子線程只負責讀取數據和響應數據,耗時的業務處理則丟給 Worker 線程池去處理。這種通過把完整任務層層分發下去,每個組件需要處理的內容就會變的很簡單,處理起來效率自然會很高。

方案的缺點:

  1. 編程復雜度非常的高;
  2. 即使一個 Reactor 主線程對應多個 Reactor 子線程,Reactor 主線程還是會存在單節點故障問題,不過真實業務場景當中,如果考慮單節點故障問題的話,一般都是通過分布式集群(Netty 集群)的方式去解決,而不是靠單節點的線程模型去解決,這里大家了解一下即可。

總的來說,主從多線程模型是應用比較多的一種線程模型,包括 Nginx 主從 Reactor 多線程模型、Memcached 主從多線程模型、Netty 主從多線程模型等知名開源框架的。

5. 模型對比

Reactor 模型和傳統的 IO 模型對比

傳統 IO 模型 Reactor 模型
線程分配 為每個客戶端都分配獨立的線程,該線程負責全部的工作(包括:監聽、讀取、處理、響應) 統一的監聽客戶端請求,并且把功能細分,并且分配給不同的子線程去處理
堵塞點 在每個子線程的 read () 方法進行堵塞 只在 select () 堵塞,select () 是所有客戶端共用的入口點
整體性能 并發量相對有限 可以處理高并發

Reactor 的整體優點如下:

  1. 性能好,Reactor 本身雖然是同步的,但是是非堵塞的,可以快速的響應;
  2. 擴展性好,可以根據 CPU 的核數來調整 Reactor 的實例個數,充分的利用 CPU 資源;
  3. 復用性好,它是一種思想,可以靈活的運用到不同的中間件、底層框架上。

三種 Reactor 線程模型對比

單 Reactor 單線程 單 Reactor 多線程 主從多線程
功能 一個線程負責所有業務 一個線程服務監聽、事件處理、轉發,多個線程負責邏輯處理 一個線程負責監聽,多個線程負責事件處理、轉發,多個線程負責邏輯處理
線程 一個線程 一個線程,一個線程組 一個線程,兩個線程組
性能
高可用

6. 小結

通過這幾個小節的講解,相信大家對 Reactor 線程模型都已經有了一定的了解了,其實我們只需要了解這幾種模型的架構思想即可。Reactor 它是一種思想,而并非是 Netty 所特有的,常見的中間件 Nginx、Redis 等底層通訊也都是基于 Reactor 思想去實現。只有把 Reactor 模型理解了,后期在閱讀源碼時才能更好的理解 Netty。