记一次spring cloud gateway Netty线程性能优化(附带压测)

这里是weihubeats ,觉得文章不错可以关注公众号小奏技术,文章首发。拒绝营销号,拒绝标题党

Spring cloud gateway version

  • 3.1.4

背景

线上的api-gateway网关在请求量过大的时候会偶尔出现如下报错

java 复制代码
io.netty.channel.ConnectTimeoutException: connection timed out:

这说明网关存在一定的性能瓶颈,需要对网关进行性能优化或者扩容pod

Spring cloud gateway IO模型

我们通过查看Spring cloud gateway源码发现Spring cloud gateway使用的IO通信sdk主要是使用的reactor.netty

初始化会去构建一个DefaultLoopResources

在创建DefaultLoopResources的时候我们看看他的一些构造参数

熟悉Netty的IO模型我们就能知道上面最核心的两个线程配置

  • IO_WORKER_COUNT
  • IO_SELECT_COUNT

一个是select线程数,一个是work线程数

其中可以看到IO_WORKER_COUNTwork线程数,默认是cpu核数,最大值为4 IO_SELECT_COUNT的线程数默认是-1,即不设置与IO_WORKER_COUNT共享一个线程池

一般我们传统的Netty通信配置都是会设置一个Boss线程池和一个Work线程池

如果BossWork线程池公用一个会影响性能。也就是说Spring cloud gateway 默认是非主从Reactor多线程模式

大概是这样

java 复制代码
EventLoopGroup eventGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(eventGroup);

我们在开发Netty应用的时候一般都会使用主从Reactor多线程模式。 也就是如下方式

java 复制代码
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossGroup,workGroup);

所以可以我们最好设置- IO_SELECT_COUNT线程数。

这个参数spring cloud gateway没有提供配置的方式。只能通过系统参数去设置

如何设置IO_SELECT_COUNT

java 复制代码
System.setProperty(ReactorNetty.IO_SELECT_COUNT,"1");

压测

实践是检验真理的唯一标准。这里我们通过压测添加IO_SELECT_COUNT和不添加IO_SELECT_COUNT配置进行压测看看spring cloud gateway的性能表现如何

压测环境

  • 机器配置:Apple M1 hw.physicalcpu: 8
  • os版本: 13.4 (22F66)

jmeter设置

3000个线程,循环两次。1秒执行

这里如果不会Jmeter可以参考我之前的使用教程: blog.csdn.net/qq_42651904...

注意新版本的Jmeter默认返回的请求结果只有200个,如果需要观察全部可以修改配置jmeter.properties

properties 复制代码
#view.results.tree.max_results=0

把这个注释的#去掉

测试路由服务接口

java 复制代码
@GetMapping("/test")
public  List<StudentVO> test(String name) throws Exception{
    TimeUnit.MILLISECONDS.sleep(500);
    return mockSelectSql();
}

请求的接口故意休眠500毫秒,模拟存在一定耗时

压测结果

  • 无任何配置
序号 average Max error%
1 5330 7776 0.35%
2 4436 9301 8.03%
3 3629 8977 18.55%
4 3164 8074 26.02%
5 5156 7815 1.37%
6 3907 9002 13.63%
7 3871 9759 15%
8 3557 8527 19.97%
  • 新增IO_SELECT_COUNT = 1
序号 average Max error%
1 5151 8051 5.45%
2 5260 8081 2.88%
3 5371 7732 0.33%
4 5785 8078 0.00%
5 5613 8190 2.48%
6 5397 8036 0.37%
7 1275 2773 0.00%
8 5664 8241 0.12%
9 5746 8589 0.00%

总结

可以看到增加IO_SELECT_COUNT线程数配置 可以明显减少error错误,即减少connection timed。目前是在mac测试数据,预计至少有20%左右的QPS提升

其次还有一个可配置参数DEFAULT_IO_WORKER_COUNT,默认为cpu核数,最大为4 如果cpu核数够多也可以增加该线程数,由于本机线程数有限,增加该线程数性能提升不明显

相关推荐
你不是我我1 小时前
【Java 开发日记】HTTP3 性能更好,为什么内网微服务依然多用 HTTP2?HTTP2 内网优势是什么?
java·开发语言·微服务
Filwaod1 小时前
互联网大厂Java面试实战:Spring Boot微服务架构与AI技术栈深度解析
spring boot·微服务·大厂面试·java面试·技术干货·ai技术栈·程序员求职
AI人工智能+电脑小能手3 小时前
【大白话说Java面试题】【Java基础篇】第32题:Java的异常处理机制是什么
java·开发语言·后端·面试
ltl3 小时前
Softmax 与概率分布:从分数到选择的桥
后端
刀法如飞4 小时前
Claude Code Skills 推荐:2026年最值得安装的10个AI技能
前端·后端·ai编程
IT_陈寒5 小时前
Vite热更新失效?你可能漏了这个小细节
前端·人工智能·后端
浮游本尊6 小时前
服务请求附件:从上传到预览、下载的实现详解
后端
程序员辉哥6 小时前
从零构建Agent智能体系列01-从零理解智能体
后端·openai·ai编程
客场消音器7 小时前
我用两周半 Vibe Coding 做了一个前额叶训练的微信小程序
前端·javascript·后端