Netty4(十五): 优化
2018-07-13 本文已影响8人
聪明的奇瑞
BossGroup 线程池优化
- Netty 是基于 Reactor 模型实现的网络框架,但 Netty 并没有实现 Reactor 模型中的主从多线程模型,默认 NioEventLoopGroup 线程池中线程数量为 CPU核心数*2,但服务器的 ServerSocketChannel 只会绑定到 bossGroup 中的一个线程。所以 bossGroup 设置多个线程并没有什么作用,反倒会浪费系统资源,因此建议将该线程池的线程数设置为 1
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
通用参数配置
ALLOCATOR-使用 ByteBuf 内存池
- 配置 ByteBuf 的分配器,使用 ByteBuf 内存池,需要内存时从内存池中分配,用完再归还给内存池,可以重复利用,避免每次使用内存时所带来的内存创建和销毁的开销,且补容易形成内存碎片
- 需要注意使用 PooledByteBufAllocator 内存池分配器分配的内存在使用完成后必须搭配 ReferenceCountUtil.release(msg); 手动进行释放,否则会造成内存泄露
- 默认为 ByteBufAllocator.DEFAULT,在 4.0 版本前为 UnpooledByteBufAllocator,4.1 版本后为 PooledByteBufAllocator。该值也可以使用系统参数io.netty.allocator.type配置,使用字符串值:”unpooled”,”pooled”
bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
bootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
ServerSocketChannel 配置
SO_BACKLOG - 指定套接字排队最大连接个数
- 当服务器请求接收线程全满时,用于临时存放已完成三次握手的请求的队列最大的长度,如果未设置或所设置的值小于 1 则采用 Java 默认值 50
- 合理的配置该值可以在服务器处理能力达到饱和的情况下用队列暂存用户取得请求,等服务器空闲时再从队列中取出请求来处理,而不是马上拒绝掉
.option(ChannelOption.SO_BACKLOG,256)
SocketChannel 配置
SO_KEEPALIVE - 启用心跳检测机制
- 是否启用心跳保活机制,在双方 TCP 套接字建立连接后如果两小时内没有进行数据交换,TCP 就会自动向对端发送一个存活检测,将会发生三种情况:
- 对端响应 ACK :则通信正常,不做任何操作
- 对端响应 REST:告知本端 TCP,对端奔溃且已重新启动
- 对端无响应:TCP 将另外发送 8 个检测请求,每个请求间隔 75 秒,若仍无得到任何响应则放弃,套接字关闭
.option(ChannelOption.SO_KEEPALIVE,true)
TCP_NODELAY - 关闭 Nagle 算法
- 在 TCP/IP 协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送 ACK 表示确认。为了尽可能的利用网络带宽,TCP 总是希望尽可能的发送足够大的数据。这里就涉及到一个名为 Nagle 的算法,该算法的目的就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块
- TCP_NODELAY 默认值为 false
- 如果要求高实时性,有数据发送时就马上发送,就将该选项设置为true 关闭 Nagle 算法
- 如果要减少发送次数减少网络交互,就设置为 false 等累积一定大小后再发送,该算法适用于小数据包、高延迟的场合
childOption(ChannelOption.TCP_NODELAY, true);