You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Boot WebFlux中Reactor Netty与Tomcat嵌入式服务器调优及问题咨询

Spring Boot WebFlux + Reactor Netty 配置与调优指南

负载测试错误分析

  • org.springframework.dao.DataAccessResourceFailureException: Failed to obtain R2DBC Connection:最可能是R2DBC连接池耗尽,或是数据库端连接数达上限导致无法获取新连接;也可能是连接等待时间超过max-acquire-time触发超时。
  • java.net.SocketException: Socket Closed:可能是客户端(JMeter)因超时主动断开连接,或是服务器端触发空闲超时关闭连接;也可能是请求处理过慢导致客户端提前终止。
  • java.net.SocketException: Socket operation on nonsocket: connect:大概率是JMeter端套接字资源耗尽,比如并发连接数过高导致客户端无法创建新套接字;也可能是网络层面的连接中断。

问题解答

1. 事件循环线程数默认值

Reactor Netty的事件循环线程数默认规则:

  • Worker线程(处理IO与请求):默认是CPU核心数 * 2,适配IO密集型场景。
  • Boss线程(接收新连接):默认1个线程,多端口监听时会自动调整。

Spring Boot未自定义时直接沿用Reactor Netty的默认值,也可通过NettyServerCustomizer自定义线程组大小。

2. Tomcat配置的Reactor Netty对应项及并发控制

Tomcat配置项Reactor Netty/Spring Boot对应方案
server.tomcat.threads.max无直接对应(非阻塞模型无需每请求一线程)。若存在阻塞操作,需使用parallel线程池,可通过spring.webflux.parallel.max-threads配置大小(默认CPU核心数)。
server.tomcat.max-connections用Spring Boot属性server.netty.max-connections配置,或通过NettyServerCustomizer自定义HttpServermaxConnections方法设置。
server.tomcat.accept-count用Spring Boot属性server.netty.backlog配置,或自定义时设置ChannelOption.SO_BACKLOG参数,控制TCP连接队列长度。

并发请求控制推荐方式

  • 数据库密集型接口:依赖R2DBC连接池max-size限制并发数据库操作,避免数据库过载。
  • CPU密集型接口:控制parallel线程池大小,防止CPU资源耗尽。
  • 全局并发限制:通过WebFilter实现请求排队限流,或使用Resilience4j的@RateLimiter注解控制并发数。

3. 各类超时配置位置

  • 连接超时
    • Spring Boot属性:server.netty.connection-timeout=5s
    • 自定义方式:通过NettyServerCustomizer设置ChannelOption.CONNECT_TIMEOUT_MILLIS
  • 空闲超时(连接空闲后自动关闭)
    通过NettyServerCustomizer配置Reactor Netty的idleTimeout
    @Bean
    public NettyServerCustomizer idleTimeoutCustomizer() {
        return httpServer -> httpServer.tcpConfiguration(tcp -> 
            tcp.idleTimeout(Duration.ofMinutes(5))
        );
    }
    
  • 请求处理超时
    • 在Reactor流中添加timeout()操作符:mono.timeout(Duration.ofSeconds(10))
    • 使用Spring 6+的@Timeout注解标记控制器方法
    • 自定义WebFilter统一添加超时逻辑
  • 响应超时
    同请求处理超时,可通过Reactor流的timeout()实现,也可配合客户端(JMeter)的响应超时配置。

4. HTTP服务器与R2DBC连接池调优分析

HTTP服务器调重点

  • 监控指标:事件循环线程负载、活跃连接数、TCP队列长度(backlog)、请求处理耗时。
  • 调优逻辑:若事件循环线程负载持续过高,说明存在阻塞操作,需将同步代码包装到Mono.fromCallable()/Flux.fromIterable()并指定parallel线程池执行。

R2DBC连接池调重点

  • 监控指标:连接池活跃数、等待队列长度、连接获取超时次数、数据库连接数使用情况。
  • 核心逻辑:max-size不能超过SQL Server的max_connections(默认100),否则数据库会拒绝新连接;若查询耗时过长,会占用连接更久导致池耗尽,需优化SQL或索引。

两者关系

如果HTTP连接限制远大于R2DBC连接池max-size,数据库密集型API的并发能力仍受限于:

  1. R2DBC连接池的最大容量
  2. 数据库服务器的最大连接数
  3. 数据库锁、查询性能(慢查询会占用连接,降低吞吐量)

5. WebFlux + r2dbc-mssql + r2dbc-pool高并发注意事项

  • 禁止阻塞操作:所有数据库操作必须是非阻塞的,不能在事件循环线程中调用同步方法(如JDBC、Thread.sleep),否则会阻塞整个事件循环,导致服务器性能骤降。
  • 连接池匹配:R2DBC的max-size必须小于等于SQL Server的max_connections,同时结合业务并发量调整,避免连接池过大导致数据库过载。
  • 事务控制:R2DBC事务绑定连接,长时间运行的事务会占用连接,需尽量缩短事务范围,避免批量操作长时间持有连接。
  • r2dbc-mssql特性:确保使用非阻塞API执行批量操作、存储过程;注意驱动对SQL Server版本的兼容性,避免语法或特性支持问题。
  • 监控与告警:启用Micrometer监控R2DBC连接池指标(r2dbc.pool.activer2dbc.pool.pending)和Reactor Netty的连接、线程指标,及时发现瓶颈。
  • Keep-Alive配置:服务器端与JMeter的Keep-Alive参数要匹配,避免频繁创建TCP连接,减少开销。

内容的提问来源于stack exchange,提问作者최광섭

火山引擎 最新活动