From 50b84a57bb1f48c1cd592902746b71a12f639a08 Mon Sep 17 00:00:00 2001 From: hongawen <83944980@qq.com> Date: Mon, 18 May 2026 08:28:33 +0800 Subject: [PATCH] =?UTF-8?q?fix(gateway):=20=E4=BC=98=E5=8C=96=E7=BD=91?= =?UTF-8?q?=E5=85=B3=E8=BF=9E=E6=8E=A5=E6=B1=A0=E5=92=8C=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=AB=AF=E4=BF=9D=E6=B4=BB=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 配置网关HttpClient连接池max-idle-time为30s,确保小于下游服务keep-alive-timeout - 设置网关连接超时时间为10s,响应超时时间为30s - 配置下游服务tomcat keep-alive-timeout为60s,避免与网关连接池形成竞争条件 - 将灰度负载均衡器日志级别从warn调整为debug,减少本地开发环境日志噪音 - 添加系统性调试技能配置到Claude设置中 --- .claude/settings.local.json | 3 ++- .../njcn/rdms/gateway/filter/grey/GrayLoadBalancer.java | 6 ++++-- rdms-gateway/src/main/resources/application.yaml | 9 +++++++++ .../src/main/resources/application.yaml | 5 +++++ .../rdms-system-boot/src/main/resources/application.yaml | 5 +++++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 1a10daf..ac21510 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -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)" ] } } diff --git a/rdms-gateway/src/main/java/com/njcn/rdms/gateway/filter/grey/GrayLoadBalancer.java b/rdms-gateway/src/main/java/com/njcn/rdms/gateway/filter/grey/GrayLoadBalancer.java index 19fefce..24e0de7 100644 --- a/rdms-gateway/src/main/java/com/njcn/rdms/gateway/filter/grey/GrayLoadBalancer.java +++ b/rdms-gateway/src/main/java/com/njcn/rdms/gateway/filter/grey/GrayLoadBalancer.java @@ -99,7 +99,8 @@ public class GrayLoadBalancer implements ReactorServiceInstanceLoadBalancer { List chooseInstances = CollectionUtils.filterList(instances, instance -> StrUtil.isEmpty(EnvUtils.getTag(instance))); // 【重要】补充说明:如果希望在 chooseInstances 为空时,不允许打到有 tag 的实例,可以取消注释下面的代码 if (CollUtil.isEmpty(chooseInstances)) { - log.warn("[filterTagServiceInstances][serviceId({}) 没有不带 tag 的服务实例列表,直接使用所有服务实例列表]", serviceId); + // 本地开发场景下所有实例都带 tag(HOSTNAME),fallback 到全集属于设计内常态、请求并未失败,降级为 debug 避免噪音 + log.debug("[filterTagServiceInstances][serviceId({}) 没有不带 tag 的服务实例列表,直接使用所有服务实例列表]", serviceId); chooseInstances = instances; } return chooseInstances; @@ -108,7 +109,8 @@ public class GrayLoadBalancer implements ReactorServiceInstanceLoadBalancer { // 情况二,有 tag 时,使用 tag 匹配服务实例 List 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; diff --git a/rdms-gateway/src/main/resources/application.yaml b/rdms-gateway/src/main/resources/application.yaml index 36cb726..99ff434 100644 --- a/rdms-gateway/src/main/resources/application.yaml +++ b/rdms-gateway/src/main/resources/application.yaml @@ -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 服务 diff --git a/rdms-project/rdms-project-boot/src/main/resources/application.yaml b/rdms-project/rdms-project-boot/src/main/resources/application.yaml index 1af3ec4..f37b4ea 100644 --- a/rdms-project/rdms-project-boot/src/main/resources/application.yaml +++ b/rdms-project/rdms-project-boot/src/main/resources/application.yaml @@ -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: diff --git a/rdms-system/rdms-system-boot/src/main/resources/application.yaml b/rdms-system/rdms-system-boot/src/main/resources/application.yaml index fcf2de5..8a4d86d 100644 --- a/rdms-system/rdms-system-boot/src/main/resources/application.yaml +++ b/rdms-system/rdms-system-boot/src/main/resources/application.yaml @@ -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 # 日志文件名,全路径