摘要:一旦某個事件觸發,相應的則會被調用,并進行處理。事實上,內部的連接處理協議編解碼超時等機制,都是通過完成的。開啟源碼之門理解了的事件驅動機制,我們現在可以來研究的各個模塊了。
Netty是什么
大概用Netty的,無論新手還是老手,都知道它是一個“網絡通訊框架”。所謂框架,基本上都是一個作用:基于底層API,提供更便捷的編程模型。那么"通訊框架"到底做了什么事情呢?回答這個問題并不太容易,我們不妨反過來看看,不使用netty,直接基于NIO編寫網絡程序,你需要做什么(以Server端TCP連接為例,這里我們使用Reactor模型):
監聽端口,建立Socket連接
建立線程,處理內容
讀取Socket內容,并對協議進行解析
進行邏輯處理
回寫響應內容
如果是多次交互的應用(SMTP、FTP),則需要保持連接多進行幾次交互
關閉連接
建立線程是一個比較耗時的操作,同時維護線程本身也有一些開銷,所以我們會需要多線程機制,幸好JDK已經有很方便的多線程框架了,這里我們不需要花很多心思。
此外,因為TCP連接的特性,我們還要使用連接池來進行管理:
建立TCP連接是比較耗時的操作,對于頻繁的通訊,保持連接效果更好
對于并發請求,可能需要建立多個連接
維護多個連接后,每次通訊,需要選擇某一可用連接
連接超時和關閉機制
想想就覺得很復雜了!實際上,基于NIO直接實現這部分東西,即使是老手也容易出現錯誤,而使用Netty之后,你只需要關注邏輯處理部分就可以了。
體驗Netty
這里我們引用Netty的example包里的一個例子,一個簡單的EchoServer,它接受客戶端輸入,并將輸入原樣返回。其主要代碼如下:
public void run() { // Configure the server. ServerBootstrap bootstrap = new ServerBootstrap( new NioServerSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); // Set up the pipeline factory. bootstrap.setPipelineFactory(new ChannelPipelineFactory() { public ChannelPipeline getPipeline() throws Exception { return Channels.pipeline(new EchoServerHandler()); } }); // Bind and start to accept incoming connections. bootstrap.bind(new InetSocketAddress(port)); } 這里 EchoServerHandler 是其業務邏輯的實現者,大致代碼如下: public class EchoServerHandler extends SimpleChannelUpstreamHandler { @Override public void messageReceived( ChannelHandlerContext ctx, MessageEvent e) { // Send back the received message to the remote peer. e.getChannel().write(e.getMessage()); } }
還是挺簡單的,不是嗎?
Netty背后的事件驅動機制
完成了以上一段代碼,我們算是與Netty進行了第一次親密接觸。如果想深入學習呢?
閱讀源碼是了解一個開源工具非常好的手段,但是Java世界的框架大多追求大而全,功能完備,如果逐個閱讀,難免迷失方向,Netty也并不例外。相反,抓住幾個重點對象,理解其領域概念及設計思想,從而理清其脈絡,相當于打通了任督二脈,以后的閱讀就不再困難了。
理解Netty的關鍵點在哪呢?我覺得,除了NIO的相關知識,另一個就是事件驅動的設計思想。什么叫事件驅動?我們回頭看看 EchoServerHandler 的代碼,其中的參數: public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) ,MessageEvent就是一個事件。這個事件攜帶了一些信息,例如這里 e.getMessage() 就是消息的內容,而 EchoServerHandler 則描述了處理這種事件的方式。一旦某個事件觸發,相應的Handler則會被調用,并進行處理。這種事件機制在UI編程里廣泛應用,而Netty則將其應用到了網絡編程領域。
在Netty里,所有事件都來自 ChannelEvent 接口,這些事件涵蓋監聽端口、建立連接、讀寫數據等網絡通訊的各個階段。而事件的處理者就是 ChannelHandler ,這樣,不但是業務邏輯,連網絡通訊流程中底層的處理,都可以通過實現 ChannelHandler 來完成了。事實上,Netty內部的連接處理、協議編解碼、超時等機制,都是通過handler完成的。當博主弄明白其中的奧妙時,不得不佩服這種設計!
下圖描述了Netty進行事件處理的流程。 Channel 是連接的通道,是ChannelEvent的產生者,而 ChannelPipeline 可以理解為ChannelHandler的集合。
開啟Netty源碼之門
理解了Netty的事件驅動機制,我們現在可以來研究Netty的各個模塊了。Netty的包結構如下:
org └── jboss └── netty ├── bootstrap 配置并啟動服務的類 ├── buffer 緩沖相關類,對NIO Buffer做了一些封裝 ├── channel 核心部分,處理連接 ├── container 連接其他容器的代碼 ├── example 使用示例 ├── handler 基于handler的擴展部分,實現協議編解碼等附加功能 ├── logging 日志 └── util 工具類
在這里面, channel 和 handler 兩部分比較復雜。我們不妨與Netty官方的結構圖對照一下,來了解其功能。
具體的解釋可以看這里: http://netty.io/3.7/guide/#ar... 。圖中可以看到,除了之前說到的事件驅動機制之外,Netty的核心功能還包括兩部分:
Zero-Copy-Capable Rich Byte Buffer
零拷貝的Buffer。為什么叫零拷貝?因為在數據傳輸時,最終處理的數據會需要對單個傳輸層的報文,進行組合或者拆分。NIO原生的ByteBuffer無法做到這件事,而Netty通過提供Composite(組合)和Slice(切分)兩種Buffer來實現零拷貝。這部分代碼在 org.jboss.netty.buffer 包中。
這里需要額外注意,不要和操作系統級別的Zero-Copy混淆了, 操作系統中的零拷貝主要是用戶空間和內核空間之間的數據拷貝, NIO中通過DirectBuffer做了實現.
Universal Communication API
統一的通訊API。這個是針對Java的Old I/O和New I/O,使用了不同的API而言。Netty則提供了統一的API( org.jboss.netty.channel.Channel )來封裝這兩種I/O模型。這部分代碼在 org.jboss.netty.channel 包中。
此外,Protocol Support功能通過handler機制實現。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77663.html
摘要:簡單來說就是把注冊的動作異步化,當異步執行結束后會把執行結果回填到中抽象類一般就是公共邏輯的處理,而這里的處理主要就是針對一些參數的判斷,判斷完了之后再調用方法。 閱讀這篇文章之前,建議先閱讀和這篇文章關聯的內容。 1. 詳細剖析分布式微服務架構下網絡通信的底層實現原理(圖解) 2. (年薪60W的技巧)工作了5年,你真的理解Netty以及為什么要用嗎?(深度干貨)...
1.EventLoopGroup類結構 showImg(https://segmentfault.com/img/bVbuL9F?w=470&h=433); 重點:繼承了ScheduledExecutorService類 2.NioEventLoopGroup類結構 showImg(https://segmentfault.com/img/bVbuL9Y?w=537&h=699); 核心代碼Nio...
摘要:零前期準備文章異常啰嗦且繞彎。二是底層真正起作用的類,并且提供了大量的靜態方法。在普通的線程中,這個對象由于本身沒有的原生支持,所以只能附著在對象當中。同一個線程中如果創建多個對象,獲取到的是同一個。 零 前期準備 0 FBI WARNING 文章異常啰嗦且繞彎。 1 版本 JDK 版本 : OpenJDK 11.0.1 IDE : idea 2018.3 Netty 版本 : net...
摘要:一些想法這個系列想開很久了,自己使用也有一段時間了,利用也編寫了一個簡單的框架,并運用到工作中了,感覺還不錯,趁著這段時間工作不是很忙,來分析一波源碼,提升下技術硬實力。 一些想法 這個系列想開很久了,自己使用netty也有一段時間了,利用netty也編寫了一個簡單的框架,并運用到工作中了,感覺還不錯,趁著這段時間工作不是很忙,來分析一波源碼,提升下技術硬實力。 結構 這里先看下net...
摘要:版本選擇目前企業使用最多的版本,最為穩定。例如使用的就是版本引入了內存池等重大特性,可以有效的降低負載,使用的就是已經被廢棄了,具體可參見所以這里我搭建的源碼閱讀環境是存在的版本。 showImg(https://segmentfault.com/img/remote/1460000012398550?w=1624&h=1080); Netty 簡介 Netty 是由 JBOSS 提供...
閱讀 1309·2021-09-27 13:56
閱讀 2339·2019-08-26 10:35
閱讀 3497·2019-08-23 15:53
閱讀 1849·2019-08-23 14:42
閱讀 1233·2019-08-23 14:33
閱讀 3562·2019-08-23 12:36
閱讀 1948·2019-08-22 18:46
閱讀 997·2019-08-22 14:06