mirror of
https://gitee.com/dromara/RuoYi-Cloud-Plus.git
synced 2026-10-06 06:52:58 +08:00
fix 修复 gateway sse 连接占用连接池导致响应拒绝问题
This commit is contained in:
@@ -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>
|
||||
|
||||
+55
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user