From 11b2d28c07e139e63281842af6de7e777a04c8ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Fri, 26 Jun 2026 18:32:17 +0800 Subject: [PATCH] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20gateway=20sse=20?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E5=8D=A0=E7=94=A8=E8=BF=9E=E6=8E=A5=E6=B1=A0?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E5=93=8D=E5=BA=94=E6=8B=92=E7=BB=9D=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-gateway-mvc/pom.xml | 5 ++ .../config/GatewayHttpClientConfig.java | 55 +++++++++++++++++++ .../GatewayHttpClientProperties.java | 51 +++++++++++++++++ script/config/nacos/ruoyi-gateway-mvc.yml | 14 +++++ script/config/nacos/ruoyi-gateway.yml | 15 +++++ 5 files changed, 140 insertions(+) create mode 100644 ruoyi-gateway-mvc/src/main/java/org/dromara/gateway/config/GatewayHttpClientConfig.java create mode 100644 ruoyi-gateway-mvc/src/main/java/org/dromara/gateway/config/properties/GatewayHttpClientProperties.java diff --git a/ruoyi-gateway-mvc/pom.xml b/ruoyi-gateway-mvc/pom.xml index dc4522f60..3c3a88cf3 100644 --- a/ruoyi-gateway-mvc/pom.xml +++ b/ruoyi-gateway-mvc/pom.xml @@ -65,6 +65,11 @@ hutool-http + + org.apache.httpcomponents.client5 + httpclient5 + + cn.dev33 diff --git a/ruoyi-gateway-mvc/src/main/java/org/dromara/gateway/config/GatewayHttpClientConfig.java b/ruoyi-gateway-mvc/src/main/java/org/dromara/gateway/config/GatewayHttpClientConfig.java new file mode 100644 index 000000000..b33da1c04 --- /dev/null +++ b/ruoyi-gateway-mvc/src/main/java/org/dromara/gateway/config/GatewayHttpClientConfig.java @@ -0,0 +1,55 @@ +package org.dromara.gateway.config; + +import lombok.RequiredArgsConstructor; +import org.apache.hc.core5.util.TimeValue; +import org.apache.hc.core5.util.Timeout; +import org.dromara.gateway.config.properties.GatewayHttpClientProperties; +import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; +import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestFactory; + +/** + * 网关 HttpClient5 配置 + * + * @author RuoYi + */ +@Configuration +@RequiredArgsConstructor +public class GatewayHttpClientConfig { + + private final GatewayHttpClientProperties properties; + + /** + * Gateway MVC 使用 RestClient 转发请求,此处提供 HttpClient5 请求工厂以调整连接池参数 + */ + @Bean + @RefreshScope + public ClientHttpRequestFactory gatewayClientHttpRequestFactory(ClientHttpRequestFactorySettings settings) { + return ClientHttpRequestFactoryBuilder.httpComponents() + .withConnectionManagerCustomizer(connectionManager -> { + connectionManager.setMaxConnTotal(properties.getMaxConnTotal()); + connectionManager.setMaxConnPerRoute(properties.getMaxConnPerRoute()); + }) + .withConnectionConfigCustomizer(connectionConfig -> { + if (properties.getConnectionTimeToLive() != null) { + connectionConfig.setTimeToLive(TimeValue.of(properties.getConnectionTimeToLive())); + } + if (properties.getValidateAfterInactivity() != null) { + connectionConfig.setValidateAfterInactivity(TimeValue.of(properties.getValidateAfterInactivity())); + } + }) + .withDefaultRequestConfigCustomizer(requestConfig -> { + if (properties.getConnectionRequestTimeout() != null) { + requestConfig.setConnectionRequestTimeout(Timeout.of(properties.getConnectionRequestTimeout())); + } + if (properties.getResponseTimeout() != null) { + requestConfig.setResponseTimeout(Timeout.of(properties.getResponseTimeout())); + } + }) + .build(settings); + } + +} diff --git a/ruoyi-gateway-mvc/src/main/java/org/dromara/gateway/config/properties/GatewayHttpClientProperties.java b/ruoyi-gateway-mvc/src/main/java/org/dromara/gateway/config/properties/GatewayHttpClientProperties.java new file mode 100644 index 000000000..f8bbd65f8 --- /dev/null +++ b/ruoyi-gateway-mvc/src/main/java/org/dromara/gateway/config/properties/GatewayHttpClientProperties.java @@ -0,0 +1,51 @@ +package org.dromara.gateway.config.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +import java.time.Duration; + +/** + * 网关 HttpClient5 配置 + * + * @author RuoYi + */ +@Data +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "spring.cloud.gateway.httpclient") +public class GatewayHttpClientProperties { + + /** + * 连接池最大连接数 + */ + private Integer maxConnTotal = 1000; + + /** + * 单个路由最大连接数 + */ + private Integer maxConnPerRoute = 500; + + /** + * 从连接池获取连接的等待超时时间 + */ + private Duration connectionRequestTimeout = Duration.ofSeconds(3); + + /** + * 等待下游响应数据的超时时间,SSE 场景通常不设置 + */ + private Duration responseTimeout; + + /** + * 连接最大存活时间 + */ + private Duration connectionTimeToLive; + + /** + * 空闲连接可用性校验间隔 + */ + private Duration validateAfterInactivity = Duration.ofSeconds(30); + +} diff --git a/script/config/nacos/ruoyi-gateway-mvc.yml b/script/config/nacos/ruoyi-gateway-mvc.yml index 3a9bc5f30..85891881e 100644 --- a/script/config/nacos/ruoyi-gateway-mvc.yml +++ b/script/config/nacos/ruoyi-gateway-mvc.yml @@ -21,6 +21,20 @@ spring: gateway: # 打印请求日志(自定义) requestLog: true + # Gateway MVC 转发使用的 HttpClient5 连接池配置 + httpclient: + # 总最大连接数 + max-conn-total: 1000 + # 单个下游路由最大连接数,SSE 长连接较多时需按并发量调整 + max-conn-per-route: 500 + # 连接池满时等待可用连接的时间 + connection-request-timeout: 3s + # SSE 场景通常不设置响应超时,避免长连接被网关主动断开 + # response-timeout: 60s + # 连接最大存活时间,不配置则使用 HttpClient5 默认值 + # connection-time-to-live: 10m + # 空闲连接可用性校验间隔 + validate-after-inactivity: 30s server: webmvc: discovery: diff --git a/script/config/nacos/ruoyi-gateway.yml b/script/config/nacos/ruoyi-gateway.yml index 3ca5d36b6..8b9ee9c78 100644 --- a/script/config/nacos/ruoyi-gateway.yml +++ b/script/config/nacos/ruoyi-gateway.yml @@ -24,6 +24,21 @@ spring: requestLog: true server: webflux: + # Gateway WebFlux 转发使用的 Reactor Netty 连接池配置 + httpclient: + pool: + # 使用固定连接池,避免 SSE 长连接占满默认连接池后快速拒绝普通请求 + type: fixed + # 总最大连接数 + max-connections: 1000 + # 连接池满时等待可用连接的时间,单位毫秒 + acquire-timeout: 3000 + # 空闲连接最大保留时间 + max-idle-time: 30s + # 后台空闲连接回收间隔 + eviction-interval: 30s + # SSE 场景通常不设置响应超时,避免长连接被网关主动断开 + # response-timeout: 60s discovery: locator: lowerCaseServiceId: true