fix 修复 gateway sse 连接占用连接池导致响应拒绝问题

This commit is contained in:
疯狂的狮子Li
2026-06-26 18:32:17 +08:00
parent e266dc2f21
commit 11b2d28c07
5 changed files with 140 additions and 0 deletions
+5
View File
@@ -65,6 +65,11 @@
<artifactId>hutool-http</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
<!-- Sa-Token 权限认证 -->
<dependency>
<groupId>cn.dev33</groupId>
@@ -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);
}
}
@@ -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);
}
+14
View File
@@ -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:
+15
View File
@@ -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