Netty 系列文章之基本組件概覽

前言

在以前的文章Netty 入門初體驗簡單介紹了 Netty 服務端和客戶端的例子,下面依舊以Netty 服務端 demo 爲例,來簡單闡述下 Netty 的基本組件。java

基本組件概覽

以Netty服務端的一個例子來闡述其中用到的基本組件,代碼以下:git

public class EchoServer {
    private final int port;

    public EchoServer(int port) {
        this.port = port;
    }

    public static void main(String[] args) throws InterruptedException {
        new EchoServer(8888).start();
    }

    public void start() throws InterruptedException {
        final EchoServerHandler serverHandler = new EchoServerHandler();
        //建立EventLoopGroup,處理事件
        EventLoopGroup group = new NioEventLoopGroup();
        EventLoopGroup worker = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(group,worker)
                    //指定所使用的NIO傳輸 Channel
                    .channel(NioServerSocketChannel.class)
                    //使用指定的端口設置套接字地址
                    .localAddress(new InetSocketAddress(port))
                    //添加一個EchoServerHandler到子Channel的ChannelPipeline
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            //EchoServerHandler別標誌爲@Shareable,因此咱們能夠老是使用一樣的實例
                            socketChannel.pipeline().addLast(serverHandler);
                        }
                    });
            //異步的綁定服務器,調用sync()方法阻塞等待直到綁定完成
            ChannelFuture future = b.bind().sync();
            future.channel().closeFuture().sync();
        } finally {
            //關閉EventLoopGroup,釋放全部的資源
            group.shutdownGracefully().sync();
            worker.shutdownGracefully().sync();
        }
    }
}

複製代碼

服務端建立流程:github

  • 建立 ServerBootStrap實例
  • 設置並綁定 NioEventLoopGroup線程池
  • 經過 ServerBootStrapchannel方法設置並綁定服務端 Channel
  • 建立並初始化 ChannelPipeline
  • 添加並設置 ChannelHandler
  • 綁定並啓動監聽端口

上面簡述了服務端的建立流程,其中包含了 Netty的基本組件的使用,下面這張導圖也簡單的敘述了Netty各大組件的概念與做用服務器

netty

Channel

Channel是 Netty中的網絡操做抽象類,對應JDK底層的Socket,它除了包含基本的I/O操做,如 bind(),connect(),read(),write()以外,還包括了Netty框架相關的一些功能,如獲取 Channel的EventLoop。網絡

EventLoop

EventLoop定義了Netty的核心抽象,用於處理鏈接的生命週期中所發生的事件。EventLoop 爲Channel處理I/O操做,下圖是 Channel,EventLoop,Thread以及EventLoopGroup之間的關係(摘自《Netty In Action》):框架

eventloop

這些關係是:異步

  • 一個EventLoopGroup 包含一個或者多個EventLoop
  • 一個 EventLoop 在它的生命週期內只和一個Thread綁定
  • 全部由 EventLoop處理的 I/O事件都將在它專有的Thread上被處理
  • 一個 Channel 在它的生命週期內只註冊一個EventLoop
  • 一個 EventLoop 可能會被分配給一個或多個 Channel

EventLoopGroup實際上就是處理I/O操做的線程池,負責爲每一個新註冊的Channel分配一個EventLoop,Channel在整個生命週期都有其綁定的 EventLoop來服務。socket

而上面服務端用的 NioEventLoop 就是 EventLoop的一個重要實現類,NioEventLoop 是Netty內部的I/O線程,而 NioEventLoopGroup是擁有 NioEventLoop的線程池,在Netty服務端中通常存在兩個這樣的NioEventLoopGroup線程池,一個 "Boss" 線程池,用於接收客戶端鏈接,實際上該線程池中只有一個線程,一個 "Worker"線程池用於處理每一個鏈接的讀寫。而Netty客戶端只需一個線程池便可,主要用於處理鏈接中的讀寫操做。ide

ChannelHandler

ChannelHandler是Netty的主要組件,它主要用於對出站和入站數據進行處理,它有兩個重要的子接口:oop

  • ChannelInboundHandler——處理入站數據以及各類狀態變化
  • ChannelOutboundHandler——處理出站數據而且容許攔截全部的操做

ChannelPipeline

ChannelPipeline提供了 ChannelHandler鏈的容器,換句話說,就是一個邏輯處理鏈,用於攔截流經Channel的入站和出站事件的ChannelHandler。仍是就是當 Channel被建立時,它會被自動地分配到它的專屬的 ChannelPipeline。

channelpipline

當一個消息或者任何其餘的入站事件被讀取時,那麼它會從 ChannelPipeline的頭部開始流動,並被傳遞給第一個 ChannelInboundHandler,第一個處理完成以後傳遞給下一個 ChannelInboundHandler,一直到ChannelPipeline的尾端,與之對應的是,當數據被寫出時,數據從 ChannelOutboundHandler 鏈的尾端開始流動,直到它到達鏈的頭部爲止。

ChannelFuture

Netty中全部I/O操做都是異步的,使用ChannelFuture能夠獲取操做完成的結果,其 addListener()方法註冊了一個 ChannelFutureListener,以便在某個操做完成時(不管是否成功)獲得通知。

ByteBuf

ByteBuf是Netty中的字節緩衝區,相比於Java NIO中的 ByeBuffer,ByteBuf作了不少改進,ByteBuf的功能性和靈活性更好。

BootStrap

Netty提供的啓動輔助類,幫助Netty客戶端或服務端的Netty初始化,服務端對應的是 ServerBootStrap引導類。

小結

上面簡單的介紹了Netty的一些基本組件,後續文章會詳細對每一個組件進行分析

參考資料 & 鳴謝

相關文章
相關標籤/搜索