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