Netty 4.1 源代碼學習:線程模型

前言

本文以 netty 4.1 自帶的示例工程 netty-example 爲例,簡要介紹 netty 線程模型java

EchoServer

echo server 示例工程的代碼位於 example/src/main/java/io.netty.example/echo服務器

  • EchoClient網絡

  • EchoClientHandlersocket

  • EchoServer函數

  • EchoServerHandleroop

EchoServer 很簡單,僅包含一個 main 方法用於初始化 netty server 以及 handler,咱們來看看其中和線程模型 相關的一些代碼性能

// EchoServer.java

public static void main(String[] args) throws Exception {
    ...
    // Configure the server
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup)
          .channel(NioServerSocketChannel.class)
          ...
    } finally {
        ...
    }
}

EventLoop & EventLoopGroup

在 EchoServer 的初始化代碼中實例化了兩個對象 bossGroup 和 workerGroup,它們有着公共基類 EventLoopGroup,這個 EventLoopGroup 是 netty 線程模型的核心.net

EventLoopGroup 類名讓人聯想到 "組合模式",因此確定有個 EventLoop 類,EventLoopGroup 包含一個或多個 EventLoop 線程

變量名 bossGroup 和 workerGroup 讓人聯想到 "生產者消費者" 模型,即由 bossGroup 產生消息(事件),而後交給 workerGroup 消費。此外咱們注意到 bossGroup 和 workerGroup 使用了不一樣的構造方法,bossGroup 指定了線程個數 1,workerGroup 則沒有,爲了發揮硬件性能,通常會根據服務器 CPU 核心個數來設定 "工做者" 線程個數,咱們跟蹤空構造函數,最終會在父類 MultithreadEventExecutorGroup 中找到當未指定線程個數時(nThreads)netty 會根據 系統屬性 io.netty.eventLoopThreads 和 CPU 核心數來肯定合適的值debug

// MultithreadEventLoopGroup.java

public abstract class MultithreadEventLoopGroup extends   
    MultithreadEventExecutorGroup implements EventLoopGroup {


    private static final int DEFAULT_EVENT_LOOP_THREADS;

    static {
        DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
                "io.netty.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2));

        if (logger.isDebugEnabled()) {
            logger.debug("-Dio.netty.eventLoopThreads: {}", DEFAULT_EVENT_LOOP_THREADS);
        }
    }

    protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {
        super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);
    }
    ...
}

Channel & EventLoop

上文提到 netty 一般使用兩個 EventLoopGroup,一個用於生產一個用於消費,那麼這兩個 EventLoopGroup 是怎麼相互通訊(耦合)的呢?

總結

  • netty 使用 EventLoopGroup 類封裝線程池

  • netty 一般使用兩個EventLoopGroup,boss group 和 worker group

  • boss group 用於網絡 IO,包括接收客戶端鏈接,讀寫 socket 等,boss group 一般使用基於 NIO 的事件循環

  • worker group 用於處理 boss group 讀取的數據,或者說一般包含應用自身的業務邏輯

相關文章
相關標籤/搜索