You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Spring Boot Actuator v1.5.13自定义健康端点及子服务状态展示的配置问题

解决Spring Boot Actuator v1.5.13健康检查配置问题

咱们一步一步来搞定你遇到的这几个问题,结合你用的Actuator v1.5.x版本(注意这个版本和v2.x配置差异很大,别搞混了),直接上可落地的方案:

先明确核心目标对应的配置调整

首先先把端点前缀的问题解决,然后实现两个独立的健康检查端点,再处理状态格式的问题。

1. 修改application.properties配置

替换你原来的Actuator配置,添加端点前缀、启用自定义的connectivity端点:

############## ACTUATOR CONFIG ################
management.security.enabled=false
# 关键:设置Actuator端点的统一前缀为/actuator,解决根路径访问的问题
management.context-path=/actuator
# 关闭所有默认端点,只启用需要的
endpoints.enabled=false
endpoints.health.enabled=true
# 启用我们自定义的connectivity端点
endpoints.connectivity.enabled=true
endpoints.jmx.enabled=false
# 禁用默认的健康指示器,避免干扰自定义逻辑
management.health.defaults.enabled=false

2. 调整健康检查配置类(HealthConf)

我们要实现两个逻辑:一个是默认的/actuator/health只返回UP,另一个是/actuator/connectivity返回带子服务详情的结构。同时优化主状态始终为UP的实现:

@Configuration
public class HealthConf {

    // 给默认的/actuator/health用的指示器,始终返回UP,无额外详情
    @Bean
    HealthIndicator mainHealthIndicator() {
        return () -> Health.up().build();
    }

    // 子服务A的健康检查指示器
    @Bean("serviceA")
    HealthIndicator serviceAHealthIndicator(RestTemplate restTemplate) {
        return new ServiceHealthIndicator(serviceAURL, restTemplate);
    }

    // 子服务B的健康检查指示器
    @Bean("serviceB")
    HealthIndicator serviceBHealthIndicator(RestTemplate restTemplate) {
        return new ServiceHealthIndicator(serviceBURL, restTemplate);
    }

    // 自定义Connectivity端点,返回包含子服务状态的详情结构
    @Bean
    Endpoint<Map<String, Object>> connectivityEndpoint(Map<String, HealthIndicator> healthIndicators) {
        return new AbstractEndpoint<Map<String, Object>>("connectivity") {
            @Override
            public Map<String, Object> invoke() {
                Map<String, Object> resultMap = new HashMap<>();
                // 主状态固定为UP,不受子服务影响
                resultMap.put("status", "UP");

                // 把子服务状态统一放到details里
                Map<String, Object> detailsMap = new HashMap<>();
                healthIndicators.forEach((indicatorName, indicator) -> {
                    // 跳过主健康指示器,只处理子服务的
                    if (!"mainHealthIndicator".equals(indicatorName)) {
                        Health healthStatus = indicator.health();
                        Map<String, Object> serviceStatusMap = new HashMap<>();
                        serviceStatusMap.put("status", healthStatus.getStatus().getCode());
                        // 如果你需要把serviceA改成service-A,这里可以手动替换名称
                        detailsMap.put(indicatorName.replace("HealthIndicator", ""), serviceStatusMap);
                    }
                });

                resultMap.put("details", detailsMap);
                return resultMap;
            }
        };
    }

    // 别忘了注入RestTemplate,给子服务检查用
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

3. 优化ServiceHealthIndicator类

把serviceUrl和RestTemplate改成构造注入,代码更规范:

public class ServiceHealthIndicator implements HealthIndicator {

    private final String serviceUrl;
    private final RestTemplate restTemplate;

    public ServiceHealthIndicator(String serviceUrl, RestTemplate restTemplate) {
        this.serviceUrl = serviceUrl;
        this.restTemplate = restTemplate;
    }

    @Override
    public Health health() {
        try {
            JsonNode resp = restTemplate.getForObject(serviceUrl + "/health", JsonNode.class);
            if ("UP".equalsIgnoreCase(resp.get("status").asText())) {
                return Health.up().build();
            }
        } catch (Exception e) {
            // 这里可以加个日志,方便排查子服务健康检查失败的原因
            // log.error("Health check failed for service: {}", serviceUrl, e);
        }
        return Health.down().build();
    }
}

逐个解决你的问题

  1. 子服务状态嵌套到details中:自定义的connectivity端点会把所有子服务状态统一放到details字段下,完全符合你要的格式。
  2. 主服务状态始终为UP:默认的/actuator/health只依赖mainHealthIndicator,它固定返回UP;connectivity端点的主状态也硬编码为UP,不需要额外加mainService节点,实现更优雅。
  3. 区分两个独立检查路径:现在你有两个独立端点:
    • /actuator/health:返回{"status": "UP"}
    • /actuator/connectivity:返回{"status": "UP", "details": {"serviceA": {"status": "UP"}, "serviceB": {"status": "DOWN"}}}(如果需要把serviceA改成service-A,在connectivityEndpoint里调整名称即可)
  4. 端点通过/actuator/前缀访问:配置了management.context-path=/actuator后,所有Actuator端点都会带上这个前缀,不会再直接从根路径访问。

内容的提问来源于stack exchange,提问作者al amine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 02:44:11