溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Netty事件監(jiān)聽和處理(上)

發(fā)布時間:2020-08-11 04:46:42 來源:網(wǎng)絡 閱讀:779 作者:情情說 欄目:開發(fā)技術

通過介紹,你會了解到:

  • 事件監(jiān)聽、NIO、線程模型等相關概念;
  • Netty總體結構;
  • 事件監(jiān)聽和處理;
  • 項目實踐總結;

本篇先介紹下前兩節(jié),下一篇介紹后兩節(jié)。

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

相關概念

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

所以,先介紹下事件監(jiān)聽、責任鏈模型、socket接口和IO模型、線程模型等基本概念,對后面理解Netty的事件監(jiān)聽和處理有很大幫助。

事件監(jiān)聽

JDK監(jiān)聽器模式主要包含以下元素:

  • EventObject 事件對象
  • EventListener 事件監(jiān)聽接口
  • 自定義事件源
  • 事件觸發(fā)

模式很簡單,用戶可以自定義事件源,保存觸發(fā)對象的相關數(shù)據(jù),事件被觸發(fā)后,傳遞給注冊事件的處理者。事件監(jiān)聽接口是為了統(tǒng)一處理者方法。

舉個比較好理解的按鈕單擊事件,其中ActionListener是事件監(jiān)聽器,ActionEvent是事件對象,包含了事件源:
Netty事件監(jiān)聽和處理(上)

實現(xiàn)一套事件監(jiān)聽的具體過程:

  • 確定事件源;
  • 明確可能產生的事件,定義成不同的事件對象或事件方法;
  • 提供一個存儲結構,用于保存監(jiān)聽事件的對象,當事件發(fā)生時,會通知監(jiān)聽者;
  • 執(zhí)行回調方法,進行業(yè)務處理;

Netty事件監(jiān)聽和處理(上)

責任鏈模式

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

關于責任鏈概念,這里再簡單說下:使多個對象都有機會處理請求,從而避免請求的發(fā)送者和接受者之間的耦合關系,將這個對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理他為止。

Netty事件監(jiān)聽和處理(上)

socket

一般說NIO,主要是針對網(wǎng)絡IO,從網(wǎng)卡中讀取數(shù)據(jù),向網(wǎng)卡中寫入數(shù)據(jù),這就是監(jiān)聽器模式的數(shù)據(jù)源。

網(wǎng)絡編程主要通過操作系統(tǒng)提供的socket接口進行,通過了解socket接口可以總結出有哪些事件。

socket是用戶進程和內核網(wǎng)絡協(xié)議之間的統(tǒng)一接口。
socket也是一種特殊的文件,網(wǎng)絡通信可以看作是對文件的讀取,使得對網(wǎng)絡的控制和對文件的控制一樣方便。

Netty事件監(jiān)聽和處理(上)

NIO和IO模型

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

一個進程所占的內存包括用戶態(tài)和內核態(tài),為了安全,用戶代碼是不能直接操作內核態(tài)內存的,通過系統(tǒng)調用進行交互,比如讀取網(wǎng)絡數(shù)據(jù),交互過程如下:

Netty事件監(jiān)聽和處理(上)

用戶線程發(fā)起read請求后,需要等待數(shù)據(jù)到達才能返回,在這期間,用戶線程不能做任何事情,如果是網(wǎng)絡編程,可能有很多Socket對象進行監(jiān)聽,會創(chuàng)建大量線程被阻塞,造成資源浪費,性能下降。

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

  • 同步非阻塞IO;
  • IO多路復用;
  • 異步IO;

具體介紹,網(wǎng)上有很多資料,就不詳細說了,這里只提下IO多路復用,說說我的理解,我們項目中就是使用這種方式。

所謂多路復用,主要是操作系統(tǒng)提供給我們這種開發(fā)模式:可以把感興趣的IO事件(建立、可讀、可寫等)提前注冊,而且多個socket對象可以注冊到一個selector選擇器上,這樣就可以多個socket對象使用一個用戶線程進行監(jiān)聽,當事件發(fā)生時,會查找對應的socket進行讀、寫等操作。

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

Netty事件監(jiān)聽和處理(上)

線程模型

上面說了我對多路復用的理解,提到了一個線程監(jiān)聽多個socket,但如果socket很多,一個線程是處理不過來的。另外,事件的接收和判斷 與 數(shù)據(jù)的讀取、處理、寫入,可以在不同線程進行。

這就引出了線程模型的概念,比如Reactor和Proactor模型,具體細節(jié)就不介紹了,網(wǎng)上有很多資料,最終目的都是為了提高IO事件處理的性能。

Netty總體結構

這部分主要是了解下Netty,對其實現(xiàn)原理先不做深究。

概述

Netty 是一個異步的事件驅動的網(wǎng)絡應用程序框架,支持快速地開發(fā)可維護的高性能的面向協(xié)議的服務器和客戶端;
它駕馭了 Java 高級 API 的能力,并將其隱藏在一個易于使用的 API 之后;

Netty事件監(jiān)聽和處理(上)

  • Core(核心部分),是底層的網(wǎng)絡通訊的一些通用抽象,這部分內容是關鍵。
  • Transport Services(傳輸服務),具體的網(wǎng)絡傳輸能力的定義以及一些實現(xiàn)。
  • Protocol Support(協(xié)議支持),netty 對于一些通用協(xié)議的編碼解碼實現(xiàn)。
零拷貝

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

Netty中所指零拷貝,完全在用戶態(tài),更偏向于優(yōu)化數(shù)據(jù)操作。Netty允許我們將多段數(shù)據(jù)合并為一整段虛擬數(shù)據(jù)供用戶使用,而不需要對數(shù)據(jù)進行拷貝操作。

Netty事件監(jiān)聽和處理(上)

統(tǒng)一的通訊模型

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

Netty提供了統(tǒng)一的API編程接口,抽象了所有點對點通信操作,僅調整幾行代碼,便可切換不同的傳輸實現(xiàn):

  • 基于NIO的TCP/IP傳輸
  • 基于OIO的TCP/IP傳輸
  • 基于OIO的UDP/IP傳輸
  • 本地傳輸
事件模型

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

Netty事件監(jiān)聽和處理(上)

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

歡迎掃描下方二維碼,關注我的個人微信公眾號 ~

Netty事件監(jiān)聽和處理(上)

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI