這裏總結了常用的IO通信模型,列舉了5種形式。
傳統IO模型
1:1形式的同步阻塞IO通信模型
在基於傳統同步阻塞模型中:
ServerSocket的主要作用?
1、負責綁定IP地址
2、啓動監聽端口;
Socket的主要作用?
負責發起連接操作。
連接成功後,雙方通過輸入輸出流進(InputStream/OutputStream)行同步阻塞式通信
通信過程:
1)服務端通常由一個獨立的Acceptor線程負責監聽客戶端的連接;
2)Acceptor監聽到客戶端的連接請求後,爲每個客戶端創建一個新的線程進行鏈路處理;
3)鏈路處理線程完成客戶端請求的處理後,通過輸出流返回應答給客戶端,然後線程銷燬。
模型缺點:
1)服務端線程個數與客戶端併發訪問連接數是1:1的關係;
2)隨着客戶端併發訪問量增大,服務端線程個數線性膨脹,系統性能急劇下降。
M:N形式的同步阻塞IO通信模型
服務端通過線程池來處理多個客戶端的接入請求,通過線程池約束及調配服務端線程資源。
形成客戶端個數M:服務端線程池最大線程數N的比例關係
通信過程:
1)當有新的客戶端接入時,將客戶端Socket封裝成一個Task投遞到服務端任務隊列;
2)服務端任務線程池中的多個線程對任務隊列中的Task進行並行處理;
3)任務線程處理完當前Task後,繼續從任務隊列中取新的Task進行處理。
模型缺點:
1)BIO的讀和寫操作都是同步阻塞的,阻塞時間取決於對端IO線程的處理速度和網絡IO的傳輸速度,可靠性差;
2)當線程池中所有線程都因對端IO線程處理速度慢導致阻塞時,所有後續接入的客戶端連接請求都將在任務隊列中排隊阻塞堆積;
3)任務隊列堆積滿後,新的客戶端連接請求將被服務端單線程Acceptor阻塞或拒絕,客戶端會發生大量連接失敗和連接超時。
非阻塞式IO模型(NIO)
基礎知識
NIO模型
多路複用器Selector是NIO模型的基礎,一個多路複用器Selector可以同時輪詢多個註冊在它上面的Channel,服務端只需要一個線程負責Selector的輪詢,就可以接入成千上萬的客戶端連接。
模型優點:
1)NIO中Channel是全雙工(是說可以通過Channel 即可完成讀操作,也可以完成寫操作)的,Channel比流(InputStream/OutputStream)可以更好地映射底層操作系統的API(UNIX網絡編程模型中,底層操作系統的通道都是全雙工的,同時支持讀寫操作);
2)客戶端發起的連接操作是異步的,不需要像之前的客戶端那樣被同步阻塞;(此時,客戶端不依賴於服務器端,也就是說客戶端發完請求可以做其他其他事情)
3)一個Selector線程可以同時處理成千上萬個client的請求,而且性能不會隨着客戶端鏈接的增加而線性下降;原因:JDK的Selector在Linux等主流操作系統上通過epoll實現,它沒有連接句柄數的限制,適合做高性能高負載的網絡服務器方案
Reactor模式思想:
分而治之+事件驅動
1)分而治之
一個connection裏完整的網絡處理過程一般分爲6步:accept、read、decode、process、encode、send。
Reactor模式將每個步驟映射爲一個Task,服務端線程執行的最小邏輯單元不再是一次完整的網絡請求,而是Task,且採用非阻塞方式執行。
2)事件驅動
每個Task對應一個特定事件,當Task準備就緒時,對應的事件通知就會發出。
Reactor收到事件通知後,分發給綁定了對應事件的Handler執行Task。
NIO+單線程Reactor模式
說明:
Reactor:負責響應事件,將事件分發給綁定了該事件的Handler處理;
Handler:事件處理器,綁定了某類事件,負責執行對應事件的Task對事件進行處理;
Acceptor:就是處理客戶端鏈接connect事件的; Handler的一種,綁定了connect事件。當客戶端發起connect請求時,Reactor會將accept事件分發給Acceptor處理。
模型優缺點
a、單線程版本Reactor模型優點是不需要做併發控制,代碼實現簡單清晰;
b、缺點是不能利用多核CPU,一個線程需要執行處理所有的accept、read、decode、process、encode、send事件,如果其中decode、process、encode事件的處理很耗時,則服務端無法及時響應其他客戶端的請求事件。
NIO+多線程Reactor模式
a、使用線程池執行數據的具體處理過程decode、process、encode,提高數據處理過程的響應速度;
b、Reactor所在單線程只需要專心監聽處理客戶端請求事件accept、read、write;
此模型缺點:
a、因爲Reactor仍是單線程,無法並行響應多個客戶端的請求事件(比如同一時刻只能read一個客戶端的請求數據)。
NIO+主從多線程Reactor模式
a、採用多個Reactor,每個Reactor在自己單獨線程中執行,可以並行響應多個客戶端的請求事件;mainReactor 不再是一個單獨的NIO線程,而是一個獨立的NIO線程池, 處理鏈接請求,認證,登陸等操作
Acceptor處理完成後,將事件註冊到subReactor線程池中的某個IO線程上去,此IO線程繼續完成後面的IO操作
b、Netty採用類似這種模式,boss線程池就是多個mainReactor,worker線程池就是多個subReactor。
總結:
1、對IO模型整體有個認識,爲以後使用IO模型積累經驗
2、爲接下來深入分析Netty中的IO模型積累經驗
3、分而治之的思想,爲以後做其他框架積累經驗