fix(gateway): 优化网关连接池和服务端保活配置

- 配置网关HttpClient连接池max-idle-time为30s,确保小于下游服务keep-alive-timeout
- 设置网关连接超时时间为10s,响应超时时间为30s
- 配置下游服务tomcat keep-alive-timeout为60s,避免与网关连接池形成竞争条件
- 将灰度负载均衡器日志级别从warn调整为debug,减少本地开发环境日志噪音
- 添加系统性调试技能配置到Claude设置中
This commit is contained in:
2026-05-18 08:28:33 +08:00
parent bd05f6d593
commit 50b84a57bb
5 changed files with 25 additions and 3 deletions

View File

@@ -38,7 +38,8 @@
"PowerShell($env:JAVA_HOME = 'C:\\\\Program Files\\\\Java\\\\jdk-17'; & 'C:\\\\software\\\\apache-maven-3.8.9\\\\bin\\\\mvn.cmd' -pl rdms-project/rdms-project-boot -am test-compile '-Dsurefire.failIfNoSpecifiedTests=false' | Select-String -Pattern 'ERROR|BUILD|FAIL' | Select-Object -Last 40)",
"PowerShell($env:JAVA_HOME = 'C:\\\\Program Files\\\\Java\\\\jdk-17'; & 'C:\\\\software\\\\apache-maven-3.8.9\\\\bin\\\\mvn.cmd' -pl rdms-project/rdms-project-boot test '-Dsurefire.failIfNoSpecifiedTests=false' | Select-String -Pattern 'Tests run|BUILD|FAILED|ERROR' | Select-Object -Last 80)",
"Skill(code-review:code-review)",
"Bash(Test-Path *)"
"Bash(Test-Path *)",
"Skill(superpowers:systematic-debugging)"
]
}
}

View File

@@ -99,7 +99,8 @@ public class GrayLoadBalancer implements ReactorServiceInstanceLoadBalancer {
List<ServiceInstance> chooseInstances = CollectionUtils.filterList(instances, instance -> StrUtil.isEmpty(EnvUtils.getTag(instance)));
// 【重要】补充说明:如果希望在 chooseInstances 为空时,不允许打到有 tag 的实例,可以取消注释下面的代码
if (CollUtil.isEmpty(chooseInstances)) {
log.warn("[filterTagServiceInstances][serviceId({}) 没有不带 tag 的服务实例列表,直接使用所有服务实例列表]", serviceId);
// 本地开发场景下所有实例都带 tagHOSTNAMEfallback 到全集属于设计内常态、请求并未失败,降级为 debug 避免噪音
log.debug("[filterTagServiceInstances][serviceId({}) 没有不带 tag 的服务实例列表,直接使用所有服务实例列表]", serviceId);
chooseInstances = instances;
}
return chooseInstances;
@@ -108,7 +109,8 @@ public class GrayLoadBalancer implements ReactorServiceInstanceLoadBalancer {
// 情况二,有 tag 时,使用 tag 匹配服务实例
List<ServiceInstance> chooseInstances = CollectionUtils.filterList(instances, instance -> tag.equals(EnvUtils.getTag(instance)));
if (CollUtil.isEmpty(chooseInstances)) {
log.warn("[filterTagServiceInstances][serviceId({}) 没有满足 tag({}) 的服务实例列表,直接使用所有服务实例列表]", serviceId, tag);
// 同上:未命中 tag 时 fallback 到全集是设计内正常路径,降级为 debug
log.debug("[filterTagServiceInstances][serviceId({}) 没有满足 tag({}) 的服务实例列表,直接使用所有服务实例列表]", serviceId, tag);
chooseInstances = instances;
}
return chooseInstances;

View File

@@ -30,6 +30,15 @@ spring:
gateway:
server:
webflux:
# HttpClient 连接池配置:网关作为反向代理客户端,复用到下游服务的 keep-alive 连接。
# 必须保证 max-idle-time < 下游 server.tomcat.keep-alive-timeout当前下游为 60s
# 否则服务端先 FIN、网关池仍持有"已死连接",复用时会抛 reactor.netty.http.client.PrematureCloseException。
httpclient:
connect-timeout: 10000 # 建立连接超时,毫秒
response-timeout: 30s # 接收响应超时
pool:
max-idle-time: 30s # 闲置连接最长保留 30s严格小于下游 keep-alive-timeout(60s)
evict-in-background: 60s # 周期后台驱逐过期连接,进一步降低 race 概率
# 路由配置项,对应 RouteDefinition 数组
routes:
## system-server 服务

View File

@@ -39,6 +39,11 @@ spring:
server:
port: 48082
tomcat:
# 长连接保活时长:默认沿用 connection-timeout(20s),过短会和网关侧 HttpClient 连接池形成 race
# 导致网关复用已被服务端关闭的连接抛 PrematureCloseException。
# 必须大于网关 spring.cloud.gateway.server.webflux.httpclient.pool.max-idle-time(30s)。
keep-alive-timeout: 60s
logging:
file:

View File

@@ -39,6 +39,11 @@
server:
port: 48081
tomcat:
# 长连接保活时长:默认沿用 connection-timeout(20s),过短会和网关侧 HttpClient 连接池形成 race
# 导致网关复用已被服务端关闭的连接抛 PrematureCloseException。
# 必须大于网关 spring.cloud.gateway.server.webflux.httpclient.pool.max-idle-time(30s)。
keep-alive-timeout: 60s
logging:
file:
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径