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

基于Spring Boot Actuator实现多API健康检查的方案咨询

单个自定义HealthIndicator实现多接口健康检查方案

完全可以通过单个自定义HealthIndicator类完成所有10个接口的上下线检测,没必要为每个接口单独创建类,这样既能减少代码冗余,也更便于后续维护。

实现思路

把每个接口的检测配置(URL、请求方式、请求体、响应类型等)抽成独立的配置模型,在单个HealthIndicator中遍历所有配置,逐个执行检测,最后汇总所有接口的状态到Health响应中。

具体实现步骤

1. 定义接口检测配置模型

创建一个类来封装每个接口的检测参数:

import lombok.Builder;
import lombok.Data;
import org.springframework.http.HttpMethod;
import java.util.function.Supplier;

@Data
@Builder
public class ApiHealthCheckConfig {
    // 接口标识(用于健康响应中的详情key)
    private String apiPath;
    // 接口完整URL
    private String fullUrl;
    // 请求方式
    private HttpMethod method;
    // 动态生成请求体的Supplier(GET请求可设为null)
    private Supplier<Object> requestBodySupplier;
    // 响应类型(简单类型用这个)
    private Class<?> responseType;
    // 泛型响应类型(比如List<DTO>用这个)
    private ParameterizedTypeReference<?> parameterizedTypeReference;
}

2. 配置所有待检测的接口

用@Configuration类来初始化所有10个接口的检测配置:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.core.ParameterizedTypeReference;
import java.util.ArrayList;
import java.util.List;
import java.time.LocalDate;

@Configuration
public class ApiHealthCheckConfigProvider {

    @Bean
    public List<ApiHealthCheckConfig> apiHealthCheckConfigs() {
        List<ApiHealthCheckConfig> configs = new ArrayList<>();

        // 示例:添加你的第一个接口配置
        configs.add(ApiHealthCheckConfig.builder()
                .apiPath("v2/alarms/cumulativeDetails")
                .fullUrl("http://localhost:7072/v2/alarms/cumulativeDetails")
                .method(HttpMethod.POST)
                .requestBodySupplier(this::getCumulativeDetailsRequest)
                .parameterizedTypeReference(new ParameterizedTypeReference<List<CumulativeDetailsDTO>>() {})
                .build());

        // 依次添加其他9个接口的配置,比如:
        configs.add(ApiHealthCheckConfig.builder()
                .apiPath("v2/orders/list")
                .fullUrl("http://localhost:7072/v2/orders/list")
                .method(HttpMethod.GET)
                .responseType(String.class)
                .build());

        return configs;
    }

    // 对应第一个接口的请求体生成逻辑
    private ToolModuleRequestDTO getCumulativeDetailsRequest() {
        ToolModuleRequestDTO dto = new ToolModuleRequestDTO();
        dto.setStartDate(LocalDate.parse("2022-04-01"));
        dto.setEndDate(LocalDate.parse("2022-04-30"));
        dto.setSeverity("Critical,Error,Fatal");
        return dto;
    }
}

3. 改造自定义HealthIndicator

实现单个类完成所有接口的检测:

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.List;

@Component
public class AllApisHealthIndicator implements HealthIndicator {

    private final RestTemplate restTemplate;
    private final List<ApiHealthCheckConfig> apiHealthCheckConfigs;

    // 注入Spring管理的RestTemplate,避免重复创建实例
    public AllApisHealthIndicator(RestTemplate restTemplate, List<ApiHealthCheckConfig> apiHealthCheckConfigs) {
        this.restTemplate = restTemplate;
        this.apiHealthCheckConfigs = apiHealthCheckConfigs;
    }

    @Override
    public Health health() {
        Health.Builder healthBuilder = Health.up();
        boolean allApisUp = true;

        for (ApiHealthCheckConfig config : apiHealthCheckConfigs) {
            String apiStatus = checkSingleApi(config);
            healthBuilder.withDetail(config.getApiPath(), apiStatus);
            if ("DOWN".equals(apiStatus)) {
                allApisUp = false;
            }
        }

        // 只要有一个接口DOWN,整体状态标记为DOWN
        return allApisUp ? healthBuilder.build() : healthBuilder.down().build();
    }

    private String checkSingleApi(ApiHealthCheckConfig config) {
        try {
            HttpHeaders headers = new HttpHeaders();
            HttpEntity<?> requestEntity = new HttpEntity<>(
                    config.getRequestBodySupplier() != null ? config.getRequestBodySupplier().get() : null,
                    headers
            );

            ResponseEntity<?> response;
            if (config.getParameterizedTypeReference() != null) {
                response = restTemplate.exchange(
                        config.getFullUrl(),
                        config.getMethod(),
                        requestEntity,
                        config.getParameterizedTypeReference()
                );
            } else {
                response = restTemplate.exchange(
                        config.getFullUrl(),
                        config.getMethod(),
                        requestEntity,
                        config.getResponseType()
                );
            }

            // 自定义判断逻辑:2xx状态码视为正常
            return response.getStatusCode().is2xxSuccessful() ? "UP" : "DOWN";
        } catch (Exception e) {
            // 捕获所有请求异常(连接超时、拒绝连接、序列化失败等),标记为DOWN
            return "DOWN";
        }
    }
}

关键注意事项

  • 复用RestTemplate:不要每次检测都创建新的RestTemplate,通过Spring注入容器管理的实例,避免资源浪费。
  • 异常全捕获:必须捕获请求过程中所有可能的异常(如连接超时、网络错误等),否则单个接口的异常会导致整个健康检查端点报错,无法返回其他接口的状态。
  • 灵活判断逻辑:可以根据业务需求调整接口健康的判断标准,比如某些接口返回400但业务上视为正常,或者需要校验响应体的具体内容。
  • 动态请求体:通过Supplier动态生成请求体,适配不同接口的参数需求,保持配置的灵活性。

内容的提问来源于stack exchange,提问作者avanish rai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 16:30:44