Netty源码剖析与实战-第八周
第五章:Netty 实战进阶 把“玩具”变成产品
Netty 编程中易错点解析 • LengthFieldBasedFrameDecoder 中initialBytesToStrip 未考虑设置 会导致应用层解析的报文还有length字段 • ChannelHandler 顺序不正确 会导致错误,推荐使用v字编排 • ChannelHandler 该共享不共享,不该共享却共享 会导致handler的多线程安全问题 • 分配ByteBuf :分配器直接用ByteBufAllocator.DEFAULT 等,而不是采用ChannelHandlerContext.alloc() 会导致初始化设置的ByteBuf来源(内存池,非内存池,堆内外内存等)改变 • 未考虑ByteBuf 的释放 SimpleChannelInboundHandler会默认释放 • 错以为ChannelHandlerContext.write(msg) 就写出数据了 只写入缓存队列 • 乱用ChannelHandlerContext.channel().writeAndFlush(msg) 实际上是pipeLine所有的handler又重新走了一遍 ChannelHandlerContext.writeAndFlush只寻找下一个合适的handler写入
调优参数:调整System 参数夯实基础
• Linux 系统参数
例如:/proc/sys/net/ipv4/tcp_keepalive_time
• Netty 支持的系统参数:
例如:serverBootstrap.option(ChannelOption.SO_BACKLOG, 1024);
• SocketChannel -> .childOption
• ServerSocketChannel -> .option
调优参数: 权衡Netty 核心参数
• 参数调整要点:
• option/childOption 傻傻分不清:不会报错,但是会不生效;
• 不懂不要动,避免过早优化。
• 可配置(动态配置更好)
• 需要调整的参数:
• 最大打开文件数
• TCP_NODELAY SO_BACKLOG SO_REUSEADDR(酌情处理)
• ChannelOption
• childOption(ChannelOption.[XXX], [YYY])
• option(ChannelOption.[XXX], [YYY])
• System property
• -Dio.netty.[XXX] = [YYY]
• ALLOCATOR 与RCVBUF_ALLOCATOR
• 功能关联:
ALLOCATOR 负责ByteBuf 怎么分配(例如:从哪里分配),RCVBUF_ALLOCATOR 负责计算为接收数据接分配多少ByteBuf:
例如,AdaptiveRecvByteBufAllocator 有两大功能:
(1)动态计算下一次分配bytebuf 的大小:guess();
(2)判断是否可以继续读:continueReading()
• 代码关联:
io.netty.channel.AdaptiveRecvByteBufAllocator.HandleImpl handle = AdaptiveRecvByteBufAllocator.newHandle();
ByteBuf byteBuf = handle.allocate(ByteBufAllocator)
其中: allocate的实现:
ByteBuf allocate(ByteBufAllocator alloc)
{
return alloc.ioBuffer(guess());
}
• System property (-Dio.netty.xxx,50+ )
• 多种实现的切换:-Dio.netty.noJdkZlibDecoder
• 参数的调优: -Dio.netty.eventLoopThreads
• 功能的开启关闭: -Dio.netty.noKeySetOptimization
• 补充说明
• 一些其他重要的参数:
• NioEventLoopGroup workerGroup = new NioEventLoopGroup();
workerGroup.setIoRatio(50);
• 注意参数的关联
• 临时存放native 库的目录: -> io.netty.native.workdir > io.netty.tmpdir
• 注意参数的变更
• io.netty.noResourceLeakDetection -> io.netty.leakDetection.level
项目Demo地址