Netty事件監聽和處理(上)【有福利】

情情說發表於2018-04-03

陪產假結束了,今天又開始正常上班了,正好趕上米粉節活動,又要忙上一陣了,米粉節活動時間為4.03 - 4.10,有不少優惠,感興趣的可以關注mi.com或小米商城app。

今天給大家送了福利:小愛音響F碼,據說賣的比較好,不太好搶到,藉著這次公司福利,分享給大家,以表大家的支援和鼓勵。

掘金的運營真的很貼心,主動找到我說:我的福利文章不是技術型文章,不能推送到資訊流,只能在個人主頁看到,為了讓更多的人蔘與這次抽取,建議寫一篇技術文章,末尾加上送福利的內容。再次感謝掘金運營小哥「刺客」的貼心和建議。

RabbitMQ實戰的後續章節還沒來得及看,這篇就總結下之前在專案組分享過的技術點:Netty事件監聽和處理。

通過介紹,你會了解到:

  • 事件監聽、NIO、執行緒模型等相關概念;
  • Netty總體結構;
  • 事件監聽和處理;
  • 專案實踐總結;

本篇先介紹下前兩節,下一篇介紹後兩節。

本篇最後會說明下福利的抽取規則,大家積極參與 >_<

相關概念

Netty是一個NIO框架,它將IO通道的建立、可讀、可寫等狀態變化,抽象成事件,以責任鏈的方式進行傳遞,可以在處理鏈上插入自定義的Handler,對感興趣的事件進行監聽和處理。

所以,先介紹下事件監聽、責任鏈模型、socket介面和IO模型、執行緒模型等基本概念,對後面理解Netty的事件監聽和處理有很大幫助。

事件監聽

JDK監聽器模式主要包含以下元素:

  • EventObject 事件物件
  • EventListener 事件監聽介面
  • 自定義事件源
  • 事件觸發

模式很簡單,使用者可以自定義事件源,儲存觸發物件的相關資料,事件被觸發後,傳遞給註冊事件的處理者。事件監聽介面是為了統一處理者方法。

舉個比較好理解的按鈕單擊事件,其中ActionListener是事件監聽器,ActionEvent是事件物件,包含了事件源:

Netty事件監聽和處理(上)【有福利】

實現一套事件監聽的具體過程:

  • 確定事件源;
  • 明確可能產生的事件,定義成不同的事件物件或事件方法;
  • 提供一個儲存結構,用於儲存監聽事件的物件,當事件發生時,會通知監聽者;
  • 執行回撥方法,進行業務處理;

事件監聽

責任鏈模式

主要是說事件處理者的組織方式,通過責任鏈模式,可以在任何處理節點,新增自定義處理器,很方便。

關於責任鏈概念,這裡再簡單說下:使多個物件都有機會處理請求,從而避免請求的傳送者和接受者之間的耦合關係,將這個物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理他為止。

責任鏈模式

socket

一般說NIO,主要是針對網路IO,從網路卡中讀取資料,向網路卡中寫入資料,這就是監聽器模式的資料來源。

網路程式設計主要通過作業系統提供的socket介面進行,通過了解socket介面可以總結出有哪些事件。

socket是使用者程式和核心網路協議之間的統一介面。 socket也是一種特殊的檔案,網路通訊可以看作是對檔案的讀取,使得對網路的控制和對檔案的控制一樣方便。

sokcet介面

NIO和IO模型

NIO是指非阻塞IO,我們一般說的IO都是阻塞IO,想全面瞭解這些概念,又會說的很多,這裡就簡單概括下。

一個程式所佔的記憶體包括使用者態和核心態,為了安全,使用者程式碼是不能直接操作核心態記憶體的,通過系統呼叫進行互動,比如讀取網路資料,互動過程如下:

同步阻塞

使用者執行緒發起read請求後,需要等待資料到達才能返回,在這期間,使用者執行緒不能做任何事情,如果是網路程式設計,可能有很多Socket物件進行監聽,會建立大量執行緒被阻塞,造成資源浪費,效能下降。

針對這種情況,出現了IO模型的概念,有幾種方式:

  • 同步非阻塞IO;
  • IO多路複用;
  • 非同步IO;

具體介紹,網上有很多資料,就不詳細說了,這裡只提下IO多路複用,說說我的理解,我們專案中就是使用這種方式。

所謂多路複用,主要是作業系統提供給我們這種開發模式:可以把感興趣的IO事件(建立、可讀、可寫等)提前註冊,而且多個socket物件可以註冊到一個selector選擇器上,這樣就可以多個socket物件使用一個使用者執行緒進行監聽,當事件發生時,會查詢對應的socket進行讀、寫等操作。

之前做過NIO開發的朋友,可以看下面的示例回顧下整個過程:

java NIO示例

執行緒模型

上面說了我對多路複用的理解,提到了一個執行緒監聽多個socket,但如果socket很多,一個執行緒是處理不過來的。另外,事件的接收和判斷 與 資料的讀取、處理、寫入,可以在不同執行緒進行。

這就引出了執行緒模型的概念,比如Reactor和Proactor模型,具體細節就不介紹了,網上有很多資料,最終目的都是為了提高IO事件處理的效能。

Netty總體結構

這部分主要是瞭解下Netty,對其實現原理先不做深究。

概述

Netty 是一個非同步的事件驅動的網路應用程式框架,支援快速地開發可維護的高效能的面向協議的伺服器和客戶端; 它駕馭了 Java 高階 API 的能力,並將其隱藏在一個易於使用的 API 之後;

Netty總體結構

  • Core(核心部分),是底層的網路通訊的一些通用抽象,這部分內容是關鍵。
  • Transport Services(傳輸服務),具體的網路傳輸能力的定義以及一些實現。
  • Protocol Support(協議支援),netty 對於一些通用協議的編碼解碼實現。

零拷貝

廣義的零拷貝是指計算機操作的過程中,CPU不需要為資料在記憶體之間的拷貝消耗資源。Linux中的sendfile()以及 Java NIO 中的FileChannel.transferTo()方法都實現了零拷貝的功能,而在 Netty 中也通過在FileRegion中包裝了 NIO 的FileChannel.transferTo()方法實現了零拷貝。

Netty中所指零拷貝,完全在使用者態,更偏向於優化資料操作。Netty允許我們將多段資料合併為一整段虛擬資料供使用者使用,而不需要對資料進行拷貝操作。

Netty零拷貝

統一的通訊模型

傳統的JAVA IO API 在應對不同的傳輸協議時,需要使用不同的型別和方法,例如:java.net.Socket和java.net.DatagramSocket,它們並不具有相同的超型別;Java新的IO API與原有的阻塞式IO API也不相容;

Netty提供了統一的API程式設計介面,抽象了所有點對點通訊操作,僅調整幾行程式碼,便可切換不同的傳輸實現:

  • 基於NIO的TCP/IP傳輸
  • 基於OIO的TCP/IP傳輸
  • 基於OIO的UDP/IP傳輸
  • 本地傳輸

事件模型

也就是要說的事件監聽和處理,提供了很好的方式去處理各種事件。

Netty事件模型

大致處理過程如上圖,具體將在下一篇介紹。


福利說明

最後,說下福利:小愛音響F碼。

準備了2份,主要為了感謝「微信公眾號」和「掘金社群」的朋友,每一份包括1個小愛音響F碼和1個小愛音響 mini F碼,可同時參加。

小米手機F碼源自於英文單詞”Friend”,是小米公司提供給小米核心使用者及為小米做出貢獻的網友的優先購買權,如果您有小米F碼的話無需等待即可直接利用小米F碼購買相關產品!

簡單來說,F碼就是不用搶了,可以直接購買 ~

抽獎截止時間

4月9號中午12點

抽獎規則

掘金社群
  • 需要關注我的掘金賬號才有效,個人主頁

  • 使用微信抽獎助手隨機抽取for掘金社群;

    掘金抽獎

微信公眾號
  • 需要關注我的微信公眾號才有效;

    情情說

  • 使用微信抽獎助手隨機抽取for微信公眾號;

    微信公眾號抽獎

相關文章