Netty工作原理架構

初始化並啓動Netty服務端過程如下:

public static void main(String[] args) {
       // 創建mainReactor
       NioEventLoopGroup boosGroup = new NioEventLoopGroup();
       // 創建工作線程組
       NioEventLoopGroup workerGroup = new NioEventLoopGroup();

       final ServerBootstrap serverBootstrap = new ServerBootstrap();
       serverBootstrap 
                // 組裝NioEventLoopGroup 
               .group(boosGroup, workerGroup)
                // 設置channel類型爲NIO類型
               .channel(NioServerSocketChannel.class)
               // 設置連接配置參數
               .option(ChannelOption.SO_BACKLOG, 1024)
               .childOption(ChannelOption.SO_KEEPALIVE, true)
               .childOption(ChannelOption.TCP_NODELAY, true)
               // 配置入站、出站事件handler
               .childHandler(new ChannelInitializer<NioSocketChannel>() {
                   @Override
                   protected void initChannel(NioSocketChannel ch) {
                       // 配置入站、出站事件channel
                       ch.pipeline().addLast(...);
                       ch.pipeline().addLast(...);
                   }
   });

       // 綁定端口
       int port = 8080;
       serverBootstrap.bind(port).addListener(future -> {
           if (future.isSuccess()) {
               System.out.println(new Date() + ": 端口[" + port + "]綁定成功!");
           } else {
               System.err.println("端口[" + port + "]綁定失敗!");
           }
       });
}

基本過程如下:

  1. 初始化創建2個NioEventLoopGroup,其中boosGroup用於Accetpt連接建立事件並分發請求,
    workerGroup用於處理I/O讀寫事件和業務邏輯
  2. 基於ServerBootstrap(服務端啓動引導類),配置EventLoopGroup、Channel類型,連接參數、配置入站、出站事件handler
  3. 綁定端口,開始工作

結合上面的介紹的Netty Reactor模型,介紹服務端Netty的工作架構圖:

server端包含1個Boss NioEventLoopGroup和1個Worker NioEventLoopGroup,NioEventLoopGroup相當於1個事件循環組,這個組裏包含多個事件循環NioEventLoop,每個NioEventLoop包含1個selector和1個事件循環線程。

每個Boss NioEventLoop循環執行的任務包含3步:

  1. 輪詢accept事件
  2. 處理accept I/O事件,與Client建立連接,生成NioSocketChannel,並將NioSocketChannel註冊到某個Worker NioEventLoop的Selector上
  3. 處理任務隊列中的任務,runAllTasks。任務隊列中的任務包括用戶調用eventloop.execute或schedule執行的任務,或者其它線程提交到該eventloop的任務。

每個Worker NioEventLoop循環執行的任務包含3步:

  1. 輪詢read、write事件;
  2. 處I/O事件,即read、write事件,在NioSocketChannel可讀、可寫事件發生時進行處理
  3. 處理任務隊列中的任務,runAllTasks。

其中任務隊列中的task有3種典型使用場景
1. 用戶程序自定義的普通任務

ctx.channel().eventLoop().execute(new Runnable() {
   @Override
   public void run() {
       //...
   }
});

2. 非當前reactor線程調用channel的各種方法

例如在推送系統的業務線程裏面,根據用戶的標識,找到對應的channel引用,然後調用write類方法向該用戶推送消息,就會進入到這種場景。最終的write會提交到任務隊列中後被異步消費。

3. 用戶自定義定時任務

ctx.channel().eventLoop().schedule(new Runnable() {
   @Override
   public void run() {
   }
}, 60, TimeUnit.SECONDS);

技術討論 & 疑問建議 & 個人博客

版權聲明: 本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 許可協議,轉載請註明出處!

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