Netty學習(六)----Netty基礎組件入場介紹

Bootstrap 、ServerBootStrap


Bootstrap 意思是引導,一個netty應用通常由一個Bootstrap開始,它主要作用是配置整個Netty程序,串聯各個組件。Bootstrap、ServerBootStrap 分別對應客戶端啓動引導類與服務啓動引導類

客戶端聲明:

  Bootstrap bootstrap = new Bootstrap();
        NioEventLoopGroup group = new NioEventLoopGroup();

        bootstrap.group(group)
                .channel(NioSocketChannel.class)
                //對NioSocketChannel 可以綁定屬性
                .attr(AttributeKey.newInstance("key"), "values")
                //option可以設置tcp相關的屬性
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .option(ChannelOption.TCP_NODELAY, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) {
                        ch.pipeline().addLast(new NettyClientHandler());
                    }
                });

服務端聲明:

 ServerBootstrap serverBootstrap = new ServerBootstrap();

        //--|--線程模型
        //-------|--賦值監聽端口,真正的跟客戶端處理會交給workerGroup
        NioEventLoopGroup boss = new NioEventLoopGroup();
        //-------|--新連接的線程組,表示處理每一條連接的數據讀寫的線程組
        NioEventLoopGroup worker = new NioEventLoopGroup();

        //----|連接處理邏輯
        ChannelInitializer<NioSocketChannel> nioSocketChannel = new ChannelInitializer<NioSocketChannel>() {
            @Override
            protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {

                System.out.println("Server init ChannelInitializer");
                nioSocketChannel.pipeline().addLast(new NettyServerHandler());

            }

        };


        //--|引導類 based on  線程模型+I/O模型+讀寫處理邏輯
        serverBootstrap
                .group(boss, worker)//設置引導類
                //--|I/O 模型
                .channel(NioServerSocketChannel.class)
                .hander(null)//該handler對應的是boosGroup
                .childHandler(nioSocketChannel)//該handler對應的是workGroup
                //--NioServerSocketChannel channelClass 設置附加屬性
                .attr(AttributeKey.newInstance("ss_keys"), "values")
                //--NioServerSocketChannel 設置附加TCP相關屬性
                .option(ChannelOption.SO_BACKLOG, 1024)//線程隊列得到的連接個數
                //----給每一條連接指定自定義屬性
                .childAttr(AttributeKey.newInstance("s_keys"), "values")
                //----給子連接提供TCP 比較基礎的設置
                .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
                .childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE);

Channel


  1. Netty網絡通信的組件,能夠用於執行網絡I/O操作
  2. 通過Channel可獲得當前網絡連接的通道狀態
  3. 通過Channel可獲得網絡連接的配置參數(如緩衝池大小)
  4. Channel提供異步的網絡I/O操作(如建立連接、讀寫、綁定端口),異步調用意味着任何I/O調用都會立即返回,並且不保證在調用結束時相關I/操作已經完成。
  5. 調用將同步返回一個ChannelFuture實例,通過註冊監聽器到ChannelFuture上,可以I/O操作成功、失敗或取消時等相關事件回調。
  6. 支持關聯I/O操作與對應的處理程序
  7. 不同協議、不同的阻塞類型的連接都有不同的Channel類型與之對應,常用的Channel類型有 :

7.1. NioSocketChannel ,異步的客戶端Tcp Socket。
7.2. NioServerSocketChannel , 異步的服務器端Tcp Socket連接。
7.3. NioDatagramChannel , 異步的UDP連接。
7.4. NioSctpChannel ,異步的客戶端Sctp連接。
7.5. NioSctpServerChannel ,異步的Sctp服務端連接,這些通道囊括了所有的UDP和TCP網絡I/O以及文件I/O。

Selector


  1. Netty基於Selector對象實現I/O多路複用,通過Selector一個線程可以監聽多個連接的Channel事件。
  2. 當向一個Selector中註冊Channel後,Selector內部的機制就可以自動不斷地查詢(Select)這些註冊的Channel是否有已就緒的I/O事件,已做到一個線程可以高效地管理多個Channel。

ChannelHandler 接口及其實現


  1. ChannelHandler 是一個接口,處理I/O事件或攔截I/O操作,並將其轉發其ChannelPipeline(業務處理鏈)中的下一個處理程序。
  2. ChannelHandler 本身並沒有提供很多方法,因爲這個接口有許多的方法需要實現,以做到子類去繼承實現。
    如:channelRead 、channelReadComplete、channelActive。
  3. ChannelHandler 及子類
    ChannelHandler 及子類
    3.1 ChannelInboundHander 用於處理入棧I/O事件;
    3.2 ChannelOutboundHander 用於處理出棧I/O事件;
    3.3 ChannelInboundHandlerAdapter 適配器 -> 用於處理入棧I/O事件;
    3.4 ChannelOutboundHandlerAdapter 適配器 -> 用於處理出棧I/O事件;
    3.5 ChannelDuplexHandler 用於處理入棧與出棧事件。

Pipeline 和 ChannelPipeline


  1. ChannelPipeline是一個Handler的集合,負責處理和攔截inbound或者outbound的事件和操作,相當於一個貫穿Netty訂單鏈。ChannelPipeline是保存了ChannelHandler的list,用於處理或攔截Channel的入棧事件和出棧操作。
  2. ChannelPipeline實現了一種高級形式的攔截過濾器模式,使用戶可以掌控事件的處理方式,已經Channel中各個的ChannelHandler是如何相互交互的。
  3. 在Netty中每個Channel都有且僅有一個ChannelPipeline與之對應:

在這裏插入圖片描述
3.1 : 一個Channel包含了一個ChannelPipeline,而ChannelPipeline又維護了一個由ChannelHandlerContext組成的雙向鏈表,並且每個ChannelHanderContext中又關聯着一個ChannelHandler;
3.2 : 入站事件和出站事件在一個雙向鏈表中,入站事件會從鏈表head往後傳遞到最後一個入站handler,出站事件會從鏈表tail往前傳遞到最前面一個出站的handler,兩種類型的handler不會產生干擾;

ChannelHandlerContext


  1. 保存Channel相關的所有上下文信息,同時關聯一個ChannelHandler對象
  2. 既ChannelHanderContext中包含一個具體的事件處理器ChannelHandler,同時ChannelHandlerContext中也也綁定了對應的pipeline和Channel的信息,方便對ChannellHandler進行調用;

EventLoopGroup 和 NioEventLoopGroup


  1. EventLoopGroup 是一組Event的抽象 ,Netty爲了更好的利用多核CPU資源,一般會有多個EventLoop同時工作,每個EventLoop維護着一個Selector實例;
  2. EventLoopGroup提供next接口,可以從組裏面按照一定規則獲取其中一個EventLoop來處理任務。如BoosEventLoopGroup 和 WorkerEventLoopGroup。
  3. 通常一個服務端口既一個ServerSocketChannel對應一個Selector和一個EventLoop線程。
  4. BossEventLoop負責接收科幻的連接並將SocketChannel交給WorkerEventLoopGroup來進行IO處理。

BossEventLoopGroup通常是一個單線程的EventLoop,EventLoop維護着一個註冊了ServerSocketChannel的Selector實例,BossEventLoop不斷輪詢Selector將連接從事件中分離了出來,通常是 OP_ACCEPT 事件 ,然後將接收到的SocketChannel交給WorkerEventLoopGroup ,WorkerEventLoopGroup會由next選擇其中一個EventLoopGroup來將這個SocketChanel註冊到其維護的Selector,並對其後續的IO事件進行處理。

Unpooled

  1. Netty提供一個專門用來操作緩衝區(Netty的數據容器)的工具類
  2. 常用方法
    public static ByteBuf copiedBuffer(CharSequence string , Charset charset)
	@Test
    public void test() {
        //1 創建一個byte[10]
        ByteBuf buffer = Unpooled.buffer(10);
        //2 數據寫入
        for (int i = 0; i < 10; i++) {
            buffer.writeByte(i);
        }
        //3 數據讀取
        for (int i = 0; i < buffer.capacity(); i++) {
            System.out.println(buffer.getByte(i));
        }

    }

比起ByteBuffer,明顯少了惱人的flip()方法,是通過自身維護了readerIndex與writerIndex實現的;

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