Netty框架的服务端开发中创建EventLoopGroup对象时线程数量源码解析

1、NioEventLoopGroup与Reactor线程模型的对应

netty的程序的启动(在服务端一般是两个NioEventLoopGroup线程池,一个boss, 一个worker; 对于客户端一般是一个线程池)。

单线程模型:下面直接给出配置的实例:

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup)
 .channel(NioServerSocketChannel.class);
//.....

上面实例化了一个NIOEventLoopGroup,构造参数是1表示是单线程的线程池。然后接着我们调用 b.group(bossGroup) 设置了服务器端的 EventLoopGroup。 有些朋友可能会有疑惑: 我记得在启动服务器端的 Netty 程序时, 是需要设置 bossGroup 和 workerGroup 的,为什么这里就只有一个 bossGroup?  其实很简单, ServerBootstrap 重写了 group 方法:

@Override
public ServerBootstrap group(EventLoopGroup group) {
    return group(group, group);
}

因此,当传入一个 group 时, 那么 bossGroup 和 workerGroup 就是同一个 NioEventLoopGroup 了。这时候,因为 bossGroup 和 workerGroup 就是同一个 NioEventLoopGroup, 并且这个 NioEventLoopGroup 只有一个线程,这样就会导致 Netty 中的 acceptor 和后续的所有客户端连接的 IO 操作都是在一个线程中处理的。 那么对应到 Reactor 的线程模型中, 我们这样设置 NioEventLoopGroup 时, 就相当于 Reactor 单线程模型。

多线程模型:下面直接给出配置的实例:

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
 .channel(NioServerSocketChannel.class);
//...

bossGroup 中只有一个线程, 在workerGroup线程池中我没有指定线程数量,所以默认是 CPU 核心数乘以2, 因此对应的到 Reactor 线程模型中, 我们知道, 这样设置的 NioEventLoopGroup 其实就是 Reactor 多线程模型。

2、NioEventLoopGroup线程数量解析

EventLoopGroup bossGroup = new NioEventLoopGroup();

public NioEventLoopGroup() {
    this(0);
}

public NioEventLoopGroup(int nThreads) {
	this(nThreads, (Executor)null);
}

public NioEventLoopGroup(int nThreads, ThreadFactory threadFactory) {
	this(nThreads, threadFactory, SelectorProvider.provider());
}

public NioEventLoopGroup(int nThreads, Executor executor) {
	this(nThreads, executor, SelectorProvider.provider());
}

public NioEventLoopGroup(int nThreads, ThreadFactory threadFactory, SelectorProvider selectorProvider) {
	this(nThreads, threadFactory, selectorProvider, DefaultSelectStrategyFactory.INSTANCE);
}

public NioEventLoopGroup(int nThreads, ThreadFactory threadFactory, SelectorProvider selectorProvider, SelectStrategyFactory selectStrategyFactory) {
	super(nThreads, threadFactory, new Object[]{selectorProvider, selectStrategyFactory, RejectedExecutionHandlers.reject()});
}


最终调用的是这个构造函数:

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

private static final int DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));

参考内容:[netty源码分析]--EventLoopGroup与EventLoop 分析netty的线程模型

猜你喜欢

转载自blog.csdn.net/jingzi123456789/article/details/81233723