netty并发优化思路

有个基于netty的项目对并发要求较高,这里记录一下调优的过程

  1. 首先放弃常用的tomcat之类的容器方案,因为其性能不够,也不方便深入优化

  2. Spring可以继续使用,仅使用IOC部分,不使用其web模块

  3. 业务逻辑本身比较简单,主要工作是写日志,第三方服务使用云厂商提供,响应速度极快,所以一次请求可以在1毫秒内完成

  4. 借助阿里云使用5000并发压测两分钟,刚开始请求响应在几十毫秒,后来拉到两秒,最终平均响应时间高达两秒,RTS 4000+

  5. Linux上使用netty的epoll,其余继续使用nio,效果不明显

  6. 修改linux连接数量 vim /etc/sysctl.conf,修改net.core.somaxconnnet.ipv4.tcp_max_syn_backlog,然后sysctl -p

  7. 通过多种方式排查,可以认为是线程切换影响较大,可通过netstat 1查看线程切换,正常在两三千左右,压测的时候直接五六万

  8. 使用管道减少redis交互,效果不明显

  9. 将redis读写改为异步,效果明显,响应时间可在一秒内,测试10000并发,RTS也在10000+

  10. 进一步减小线程切换,将业务handler从原本的单独Group改为直接使用io线程池

  11. 将io线程数量限制为核心数+1,可通过top看到所有核心都在运转,只是使用率都不算高,整体使用率也才70%左右,所以核心数比单核性能更重要

  12. 通过arthas查看业务耗时情况,业务耗时一次不超过0.3毫秒,此时RTS依然是10000+,计算最大RTS (1000 / 0.3) * 8 = 26666,看似还有大量空间可优化,但是考虑到GC、上下文切换、其他程序竞争CPU,不好说还有多大优化空间

  13. 可通过https://gceasy.io/解析GC日志,jdk8可配置-XX:-UseAdaptiveSizePolicy -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:+PrintHeapAtGC -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=20M -Xloggc:/data/weblogs/ard-user-gc-%t.log -XX:+HeapDumpOnOutOfMemoryError 输出GC日志


netty并发优化思路
http://blog.inkroom.cn/2023/12/12/1F6HAFB.html
作者
inkbox
发布于
2023年12月12日
许可协议