高性能網絡通信框架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的單擊我
想學併發的童鞋可以 單擊我

image.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章