E04a: /actuator/** 纳入网关自身端点旁路(探活不被 oapi 链裸 404)
build / build-push (push) Successful in 1m6s

projman 探活口径 = {ctx}/actuator/health 且只认 HTTP 200;网关原先只旁路
/api/internal/**,健康探针被 TargetRouter 判未知 target 裸 404 → HealthGuard
连续失败会周期性 restart,E05/E06 的 health=200 验收也不可能达成。
台账/验签/转发四处共用同一判定,故一处改动即全链生效。
This commit is contained in:
chenxing
2026-09-22 09:25:07 +08:00
parent 0545de48a8
commit 1d354face9
4 changed files with 38 additions and 2 deletions
@@ -31,6 +31,12 @@ public class RoutingFilter implements Filter {
/** 网关自身管理端点前缀:绕开 oapi 判定链(T0.10 /api/internal/routes/refresh) */
public static final String INTERNAL_PREFIX = "/api/internal";
/**
* 探活端点前缀:projman 的探活口径是 {@code {ctx}/actuator/health},被 oapi 链裸 404
* 判死的容器会被 HealthGuard 周期性 restart,故与 {@link #INTERNAL_PREFIX} 同级旁路。
*/
public static final String ACTUATOR_PREFIX = "/actuator";
/** 路由产物 attribute({@link TargetRouter.Routing}) */
public static final String ATTR_ROUTING = "yh.gateway.routing";
/** 注册表策略 attribute({@link RouteSpec}) */
@@ -83,7 +89,10 @@ public class RoutingFilter implements Filter {
}
static boolean isGatewayInternal(String uri) {
return uri != null
&& (uri.equals(INTERNAL_PREFIX) || uri.startsWith(INTERNAL_PREFIX + "/"));
return isSelfPath(uri, INTERNAL_PREFIX) || isSelfPath(uri, ACTUATOR_PREFIX);
}
private static boolean isSelfPath(String uri, String prefix) {
return uri != null && (uri.equals(prefix) || uri.startsWith(prefix + "/"));
}
}
@@ -179,4 +179,15 @@ class GatewayChainTest {
ResponseEntity<String> resp = rest.postForEntity("/api/internal/routes/refresh", null, String.class);
assertThat(resp.getStatusCodeValue()).as("自身端点走 controller,不进 oapi 链").isEqualTo(200);
}
@Test
void actuator健康端点属自身端点_不被链拦且不入台账() throws Exception {
ResponseEntity<String> resp = rest.getForEntity("/actuator/health", String.class);
assertThat(resp.getStatusCodeValue()).as("健康探针不被 oapi 链裸 404(平台探活口径 = {ctx}/actuator/health)").isEqualTo(200);
assertThat(resp.getBody()).as("探针可读").contains("UP");
Thread.sleep(700);
assertThat(logRepository.findAll()).as("探针每 10s 一次,不得灌进 open_api 台账").isEmpty();
}
}
@@ -128,4 +128,13 @@ class GatewayEnforceChainTest {
assertThat(resp.getStatusCodeValue()).isEqualTo(200);
assertThat(CALLER_SEEN.get()).isEqualTo("100617");
}
@Test
void 收口形态下健康探针仍可达() {
ResponseEntity<String> resp = rest.getForEntity("/actuator/health", String.class);
assertThat(resp.getStatusCodeValue())
.as("observe=false 也不得拦自身探针:平台探活口径是 {ctx}/actuator/health,拦死即重启风暴")
.isEqualTo(200);
}
}
+7
View File
@@ -12,3 +12,10 @@ spring:
jpa:
hibernate:
ddl-auto: none
management:
health:
redis:
# 测试上下文没有 redis(默认 localhost:6379 连不上会让聚合探针 503);
# E04a 用例要钉的是「探针不经 oapi 链」= 平台探活口径 HTTP 200
enabled: false