一、三種網路IO模型:

分類:

  1. BIO 同步的、阻塞式 IO
  2. NIO 同步的、非阻塞式 IO
  3. AIO 非同步非阻塞式 IO

阻塞和同步的概念:

  1. 阻塞:若讀寫未完成,呼叫讀寫的執行緒一直等待
  2. 非阻塞:若讀寫未完成,呼叫讀寫的執行緒不用等待,可以處理其他工作
  3. 非同步:讀寫過程完全託管給作業系統完成,作業系統完成後通知呼叫讀寫的執行緒
  4. 同步:讀寫過程由本執行緒完成,期間可以處理其他工作,但要輪詢讀寫是否完畢

BIO 雖然可以使用執行緒池+等待佇列進行優化,避免使用過多的執行緒,但是依然無法解決執行緒利用率低的問題。

資料通過通道 Channel 傳輸,往Channel中讀寫資料需要先經過緩衝區Buffer

NIO為每個客戶端連線分配Channel和Buffer,並註冊到多路複用器 Selector上,Selector通過輪詢,找到有IO活動的連線進行處理,這種處理模式稱為Reactor模式

若當前通道無可用資料,執行緒不會阻塞,而是可以處理其他通道的讀寫

這樣 降低了執行緒的需求量,提高了執行緒的利用率 實現了IO 多路複用

IO 多路複用的定義:單個執行緒 管理多個IO流

二、Reactor模式

Reactor模式基本原理是

1)Reactor:Reactor 在一個單獨的執行緒中執行,負責監聽和分發多個客戶端的事件,分發給適當的handler執行緒來對 IO 事件做出反應。

2)Handlers:處理執行緒 會執行處理方法來 響應 I/O 事件

Reactor 模式就是實現網路 IO 程式高併發特性的關鍵。

它又可以分為單 Reactor 單執行緒模式、單 Reactor 多執行緒模式、主從 Reactor 多執行緒模式。

這種模式的基本工作流程為:

1)Reactor 通過 select 監聽客戶端請求事件,收到事件之後通過 dispatch 進行分發

2)若事件是建立連線的請求,則由 Acceptor 通過 accept 處理連線請求,然後建立一個 Handler 物件處理連線建立後的後續業務。

3)若不是建立連線的請求,則分發給此連線對應的 Handler 處理。

4)Handler 會完成 read-->業務處理-->send 的完整處理流程。

簡單來說就是:一個執行緒 處理多個連線的請求、分發、read,send、業務處理 操作

優點是:模型簡單,沒有多執行緒、程序通訊、競爭的問題,一個執行緒完成所有的事件響應和業務處理。

缺點是:

1)存在效能問題,只有一個執行緒,無法完全發揮多核 CPU 的效能。Handler 在處理某個連線上的業務時,整個程序無法處理其他連線事件,很容易導致效能瓶頸。

2)存在可靠性問題,若執行緒意外終止,或者進入死迴圈,會導致整個系統通訊模組不可用,不能接收和處理外部訊息,造成節點故障。

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

Reactor 多執行緒模式 使用了

一個Reactor主執行緒 處理 多個客戶端的 監聽 連線  分發 read和send

多個Worker執行緒 處理多個客戶端的業務

這種模式的優點是可以充分的利用多核 CPU的處理能力,

缺點是多執行緒資料共享和控制比較複雜,Reactor 處理所有的事件的監聽和響應,在單執行緒中執行,面對高併發場景還是容易出現效能瓶頸。

主從 Reactor 多執行緒模式 使用了

一個Reactor主執行緒 處理 多個客戶端的監聽,連線,分發

多個Reactor子執行緒處理多個客戶端的 read和send

多個Worker執行緒 處理多個客戶端的業務

MainReactor 只負責監聽客戶端連線請求,和客戶端建立連線之後將連線交由 SubReactor 監聽後面的 IO 事件。

這種模式的優點是:

1)MainReactor 執行緒與 SubReactor 執行緒職責明確,MainReactor 執行緒只需要接收新連線,SubReactor 執行緒完成後續的業務處理。

2)互動簡單, MainReactor 執行緒只需要把新連線傳給 SubReactor 執行緒,由SubReactor 返回資料給客戶端

3)多個 SubReactor 執行緒能夠應對更高的併發請求。

這種模式的缺點是程式設計複雜度較高。但是由於其優點明顯,在許多專案中被廣泛使用,包括 Nginx、Memcached、Netty 等。

這種模式也被叫做伺服器的 1+M+N 執行緒模式,即使用該模式開發的伺服器包含一個(或多個,1 只是表示相對較少)連線建立執行緒+M 個 IO 執行緒+N 個業務處理執行緒。這是業界成熟的伺服器程式設計模式。