java高併發實戰Netty+協程(Fiber)|系列1|事件驅動模式和零拷貝

今天開始寫一些高併發實戰系列。java

本系列主要講兩大主流框架:react

Netty和Quasar(java纖程庫)編程

先介紹netty吧,netty是業界比較成熟的高性能異步NIO框架。服務器

簡單來講,它就是對NIO2的封裝,但提供了更好用,bug更少的API。架構

爲何netty能提供高性能?核心要點有如下兩點:併發

1.Netty基於NIO2的事件驅動模式框架

2.零拷貝異步

先說,事件驅動模式吧,這個好理解,咱們慢慢分解:高併發

java原來IO操做都是阻塞的,一個IO請求一個線程,多個IO請求就要多個線程,很消耗資源。性能

如今NIO不同了,多個IO請求,一個線程(reactor),這個線程專門用來監聽不一樣事件(read,write,accept),根據事件類型分發到不一樣線程去異步處理,處理完後拿到結果返回給客戶端。原理以下圖:

 

舉個例子吧:好比你去KFC買漢堡,

1.若是是阻塞式IO的情景,是這樣的:

你:美女,給我來個雞腿堡,不要辣。

服務員小姜:好的,稍等。

而後服務員小姜,就去後臺。先炸雞腿,再烤麪包,再把雞腿放些沙拉醬,合上兩處麪包,再用紙打個包。

最後,服務員小姜,一路小跑,到前臺,把漢堡放在托盤上。

而後,小姜打開電腦跟你結帳:您好,一共19.9,謝謝。

2.若是是非阻塞式NIO的情景,是這樣的:

你:美女,給我來個雞腿堡,不要辣。

服務員小姜:好的,稍等。回頭一喊:老薑,給我來個雞腿堡。

而後服務員老薑,就去後臺。先炸雞腿,再烤麪包,再把雞腿放些沙拉醬,合上兩處麪包,再用紙打個包。

最後,服務員老薑,一路小跑,到前臺,把漢堡交給小姜,小姜把漢堡放在托盤上。

而後,小姜打開電腦跟你結帳:您好,一共19.9,送你一包薯條,謝謝。

這兩種情景,有什麼不同?

 

有同窗說,前面的情景,只有小姜一我的在幹活,很着挺累人的。並且,貌似,小姜,同一時間,只能服務一個客戶。

也有同窗說,後面加上老薑,小姜的工做輕鬆不少,也能夠同進服務多個客戶,效率也提升了很多。

也有同窗說,後面小姜,還送了一包薯條!-------好眼力,好細心!這都被你發現了!但這個不是問題的重點!年輕人不要分心啊!

這兩個場景,徹底說明了一個問題:

阻塞式IO效率很低,等待時間長,吞吐量低;非阻塞式NIO效率高,等待時間短(後臺能夠用N個老薑),吞吐量高。

從上面的例子咱們也能夠很容易理解事件驅動模式。

什麼叫事件驅動?

首先,要有事件:你要點個雞腿堡,這是個事件。

而後,這個事件被小姜「監聽」到了,這時,小姜的身份相似於NIO的selector(監聽器)。

小姜,一監聽到這個事件,立馬轉發給老薑(worker線程),老薑在後面忙活,而後沒有說話,扔給小姜一個:打包好的雞腿堡。

小姜再轉扔給你。

這就叫事件驅動模式。

 如今咱們再到說說什麼是BIO,NIO,AIO,以及它們的區別和應用場景。

  • Java BIO : 同步並阻塞,服務器實現模式爲一個鏈接一個線程,即客戶端有鏈接請求時服務器端就須要啓動一個線程進行處理,若是這個鏈接不作任何事情會形成沒必要要的線程開銷,固然能夠經過線程池機制改善。

  • Java NIO : 同步非阻塞,服務器實現模式爲一個請求一個線程,即客戶端發送的鏈接請求都會註冊到多路複用器上,多路複用器輪詢到鏈接有I/O請求時才啓動一個線程進行處理。

  • Java AIO(NIO.2) : 異步非阻塞,服務器實現模式爲一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務器應用去啓動線程進行處理,

BIO、NIO、AIO適用場景分析:

  • BIO方式適用於鏈接數目比較小且固定的架構,這種方式對服務器資源要求比較高,併發侷限於應用中,JDK1.4之前的惟一選擇,但程序直觀簡單易理解。

  • NIO方式適用於鏈接數目多且鏈接比較短(輕操做)的架構,好比聊天服務器,併發侷限於應用中,編程比較複雜,JDK1.4開始支持。

  • AIO方式使用於鏈接數目多且鏈接比較長(重操做)的架構,好比相冊服務器,充分調用OS參與併發操做,編程比較複雜,JDK7開始支持。

另外,I/O屬於底層操做,須要操做系統支持,併發也須要操做系統的支持,因此性能方面不一樣操做系統差別會比較明顯。

在高性能的I/O設計中,有兩個比較著名的模式Reactor和Proactor模式,其中Reactor模式用於同步I/O,而Proactor運用於異步I/O操做。

 

好了,今天的內容就這些,明天繼續講零拷貝。

對了,點漢堡時,別忘了跟服務員多要包薯條,畢竟這是免費的!:)

相關文章
相關標籤/搜索