美文网首页
阅读 Netty启动引导类Bootstrap模块

阅读 Netty启动引导类Bootstrap模块

作者: 日落_3d9f | 来源:发表于2020-01-07 22:57 被阅读0次
    • 服务器启动引导类ServerBootstrap

    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线程是有用的,但我没有看到它的原因。

    • 参考:https://blog.csdn.net/QH_JAVA/article/details/78443646

    • channel:设置channel通道类型NioServerSocketChannel、OioServerSocketChannel(过期不推荐使用)

    • childHandler: 用于对每个通道里面的数据处理;

    • option: 作用于每个新建立的channel,设置TCP连接中的一些参数,如下

      *   ChannelOption.SO_BACKLOG: 存放已完成三次握手的请求的等待队列的最大长度;
      *   ChannelOption.TCP_NODELAY: 为了解决Nagle的算法问题,默认是false, 要求高实时性,有数据时马上发送,就将该选项设置为true关闭Nagle算法;如果要减少发送次数,就设置为false,会累积一定大小后再发送;
      *   知识拓展: [https://baike.baidu.com/item/Nagle%E7%AE%97%E6%B3%95/5645172](https://baike.baidu.com/item/Nagle%E7%AE%97%E6%B3%95/5645172) [https://www.2cto.com/article/201309/241096.html](https://www.2cto.com/article/201309/241096.html)
      
    • childOption: 作用于被accept之后的连接

    • 客户端启动引导类Bootstrap
      • remoteAddress: 服务端地址
      • handler:和服务端通信的处理器

    补充网络安全知识

    TCP三次握手

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

    相关文章

      网友评论

          本文标题:阅读 Netty启动引导类Bootstrap模块

          本文链接:https://www.haomeiwen.com/subject/yincactx.html