1. 程式人生 > >高效能網路通訊框架Netty-基礎概念篇

高效能網路通訊框架Netty-基礎概念篇

一、前言

Netty是一種可以輕鬆快速的開發協議伺服器和客戶端網路應用程式的NIO框架,它大大簡化了TCP或者UDP伺服器的網路程式設計,但是你仍然可以訪問和使用底層的API,Netty只是對其進行了高層的抽象。

Netty的簡易和快速開發並不意味著由它開發的程式將失去可維護性或者存在效能問題。Netty是被精心設計的,它的設計參考了許多協議的實現,比如FTP,SMTP,HTTP和各種二進位制和基於文字的傳統協議,因此 Netty成功的實現了兼顧快速開發,效能,穩定性,靈活性為一體,不需要為了考慮一方面原因而妥協其他方面。

image

二、基礎概念

Channel也就是通道,這個概念是在JDK NIO類庫裡面提供的一個概念,JDK中其實現類有客戶端套接字通道java.nio.channels.SocketChannel和服務端監聽套接字通道java.nio.channels.ServerSocketChannel,Channel的出現是為了支援非同步IO操作,JDK裡面的通道是java.nio.channels.Channel。

io.netty.channel.Channel是Netty框架自己定義的一個通道介面,Netty實現的客戶端NIO套接字通道是NioSocketChannel,提供的伺服器端NIO套接字通道是NioServerSocketChannel。

  • NioSocketChannel
    客戶端套接字通道,內部管理了一個Java NIO中的java.nio.channels.SocketChannel例項,用來建立SocketChannel例項和設定該例項的屬性,並呼叫Connect方法向服務端發起TCP連結等。
  • NioServerSocketChannel
    伺服器端監聽套接字通道,內部管理了一個Java NIO中的java.nio.channels.ServerSocketChannel例項,用來建立ServerSocketChannel例項和設定該例項屬性,並呼叫該例項的bind方法在指定埠監聽客戶端的連結。
  • Channel與socket的關係
    在Netty中Channel有兩種,對應客戶端套接字通道NioSocketChannel,內部管理java.nio.channels.SocketChannel套接字,對應伺服器端監聽套接字通道NioServerSocketChannel,其內部管理自己的java.nio.channels.ServerSocketChannel套接字。也就是Channel是對socket的裝飾或者門面,其封裝了對socket的原子操作。
  • EventLoopGroup
    Netty之所以能提供高效能網路通訊,其中一個原因是因為它使用Reactor執行緒模型。在netty中每個EventLoopGroup本身是一個執行緒池,其中包含了自定義個數的NioEventLoop,每個NioEventLoop是一個執行緒,並且每個NioEventLoop裡面持有自己的selector選擇器。
    ^^
    在Netty中客戶端持有一個EventLoopGroup用來處理網路IO操作,在伺服器端持有兩個EventLoopGroup,其中boss組是專門用來接收客戶端發來的TCP連結請求的,worker組是專門用來具體處理完成三次握手的連結套接字的網路IO請求的。
  • Channel 與 EventLoop 的關係
    Netty中NioEventLoop是EventLoop的一個實現,每個NioEventLoop中會管理自己的一個selector選擇器和監控選擇器就緒事件的執行緒;每個Channel只會關聯一個NioEventLoop;
    ^^
    當Channel是客戶端通道NioSocketChannel時候,會註冊NioSocketChannel管理的SocketChannel例項到自己關聯的NioEventLoop的selector選擇器上,然後NioEventLoop對應的執行緒會通過select命令監控感興趣的網路讀寫事件;
    ^^
    當Channel是服務端通道NioServerSocketChannel時候,NioServerSocketChannel本身會被註冊到boss EventLoopGroup裡面的某一個NioEventLoop管理的selector選擇器上,而完成三次握手的連結套接字是被註冊到了worker EventLoopGroup裡面的某一個NioEventLoop管理的selector選擇器上;
    ^^
    需要注意是多個Channel可以註冊到同一個NioEventLoop管理的selector選擇器上,這時候NioEventLoop對應的單個執行緒就可以處理多個Channel的就緒事件;但是每個Channel只能註冊到一個固定的NioEventLoop管理的selector選擇器上。
  • ChannelPipeline
    Netty中的ChannelPipeline類似於Tomcat容器中的Filter鏈,屬於設計模式中的責任鏈模式,其中鏈上的每個節點就是一個ChannelHandler。在netty中每個Channel有屬於自己的ChannelPipeline,對從Channel中讀取或者要寫入Channel中的資料進行依次處理,如下圖是netty原始碼裡面的一個圖:
    image需要注意一點是雖然每個Channel(更底層說是每個socket)有自己的ChannelPipeline,但是每個ChannelPipeline裡面可以複用一個ChannelHandler。

三、總結

Netty作為高效能非同步通訊框架,其應用還是比較廣泛的,比如阿里巴巴開源的高效能Rpc框架Dubbo的網路通訊預設實現使用的是Netty, 螞蟻金服開源的金融級Sofa-Bolt 框架,底層網路通訊也是基於 Netty 來實現的,還有最近剛開源的Zuul2.0使用Netty重寫了其接受與處理請求的邏輯。

想了解JDK NIO和更多Netty基礎的可以單擊我
更多關於分散式系統中服務降級策略的知識可以單擊 單擊我
想系統學dubbo的單擊我
想學併發的童鞋可以 單擊我


加多

加多

高階 Java 攻城獅 at 阿里巴巴加多,目前就職於阿里巴巴,熱衷併發程式設計、ClassLoader,Spring等開源框架,分散式RPC框架dubbo,springcloud等;愛好音樂,運動。微信公眾號:技術原始積累。知識星球賬號:技術原始積累