netty
关于netty的学习和介绍,可以去github看官方文档,这里良心推荐《netty实战》和《netty权威指南》两本书,前者对于新手更友好,原理和应用都有讲到,多读读会发现很多高性能的优化点。
netty高性能优化点
最近参加了阿里中间价性能比赛,为了提升netty写的servive mesh的网络通信的性能,最近几天查了书、博客(这里强力推荐netty作者的博客,干货真的很多),自己总结了如下一下优化点。如果有错误希望能指正。
注:这里所讨论的对应的netty版本为netty4
首先要明确要netty优化的几个主要的关注点。
- 减少线程切换的开销。
- 复用channel,可以选择池化channel
- zero copy的应用
- 减少并发下的竞态情况
接下来将细数一下总结的优化点
1. 尽可能的复用EventLoopGroup
。
这里就要涉及netty的线程模型了。netty实战的第七章里有很细致的阐释。简单说EventLoopGroup
包含了指定数量(如果没有指定,默认是cpu核数的两倍,可以从源码中看到)的EvenetLoop
,Eve netLoop
和channel
的关系是一对多,一个channel
被分配给一个EventLoop
,它生命周期中都会使用这个EventLoop
,而EventLoop
背后就是线程。见下图。
因此如果需要使用
ThreadLocal
保存上下文,那么许多channel就会共享同一个上下文。
因此不需要每次都new出一个EventLoopGroup
,其本质上是线程分配,可以复用同一个EventLoopGroup
,减少资源的使用和线程的切换。特别是在服务端引导一个客户端连接的时候。如下:
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.childHandler(new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf byteBuf)
throws Exception {
Bootstrap bootstrap = new Bootstrap();
bootstrap.channel(NioSocketChannel.class)
.group(ctx.channel().eventLoop())
.handler(