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

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

Spring cloud gateway version

  • 3.1.4

背景

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

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多线程模式

大概是这样

EventLoopGroup eventGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(eventGroup);

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

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

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可以参考我之前的使用教程:
https://blog.csdn.net/qq_42651904/article/details/118860462

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

#view.results.tree.max_results=0

把这个注释的#去掉

测试路由服务接口

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

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

压测结果

  • 无任何配置
序号averageMaxerror%
1533077760.35%
2443693018.03%
33629897718.55%
43164807426.02%
5515678151.37%
63907900213.63%
73871975915%
83557852719.97%
  • 新增IO_SELECT_COUNT = 1
序号averageMaxerror%
1515180515.45%
2526080812.88%
3537177320.33%
4578580780.00%
5561381902.48%
6539780360.37%
7127527730.00%
8566482410.12%
9574685890.00%

总结

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

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

### Spring Cloud Gateway集成Netty配置与使用 #### 一、Spring Cloud GatewayNetty的支持特性 由于Spring Cloud Gateway基于Netty构建,因此其具备处理长连接的能力[^1]。这意味着,在设计微服务架构时,可以利用这一特点实现更高效的服务间通信。 #### 二、Netty线程池大小 为了性能表现,可以通过修改`reactor.netty.ioWorkerCount`参数来控制用于I/O操作的工作线程数量。此设置对于提升高并发场景下的响应速度至关重要。因为这个属性不支持直接在application.yml文件中定义,所以推荐采用如下方式创建自定义配置类来进行设定: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class NettyConfig { @Bean public static SystemPropertyInitializer systemProperties() { return new SystemPropertyInitializer(); } private static final class SystemPropertyInitializer implements Runnable { @Override public void run() { // 设置io工作线程的数量, 可根据实际需求整数值 System.setProperty("reactor.netty.ioWorkerCount", "8"); } } } ``` 上述代码展示了如何通过Java Bean的方式初始化JVM系统属性,从而间接达到更改Netty内部参数的目的[^2]。 #### 三、启用Websocket或其他形式的长连接支持 当涉及到WebSocket或者其他类型的持久化会话时,只需确保应用程序服务器端已经正确设置了允许此类请求的相关选项即可。通常情况下,默认配置即能满足大多数应用场景的需求;但对于特定业务逻辑,则可能还需要进一步定制化开发。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值