阅读 Netty启动引导类Bootstrap模块

2020-01-07  本文已影响0人  日落_3d9f

group :设置线程组模型,Reactor线程模型对比EventLoopGroup。NIOEventLoopGroup就是一个线程池实现,通过设置不同的NIOEventLoopGroup方式就可以对应三种不同的Reactor线程模型。这里只给出服务端的配置,对于客户端都是一样的。

单线程实例:

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 多线程模型.

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

Netty 的服务器端的 acceptor 阶段, 没有使用到多线程, 因此上面的主从多线程模型 在 Netty 的服务器端是不存在的.

服务器端的 ServerSocketChannel 只绑定到了 bossGroup 中的一个线程, 因此在调用 Java NIO 的 Selector.select 处理客户端的连接请求时, 实际上是在一个线程中的, 所以对只有一个服务的应用来说, bossGroup 设置多个线程是没有什么作用的, 反而还会造成资源浪费。

经 Google, Netty 中的 bossGroup 为什么使用线程池的原因大家众所纷纭, 不过我在 stackoverflow 上找到一个比较靠谱的答案:
the creator of Netty says multiple boss threads are useful if we share NioEventLoopGroup between different server bootstraps, but I don’t see the reason for it.
意思就是说:netty作者说:我们在不同的服务器引导之间共享NioEventLoopGroup,多个boss线程是有用的,但我没有看到它的原因。

补充网络安全知识

TCP三次握手

Linux服务器TCP连接底层知识:

上一篇下一篇

猜你喜欢

热点阅读