使用CompositeReactiveHealthContributor时指标重复显示且多次调用的问题
问题解决方法
你的问题根源在于:自定义的CustomNHealthIndicator被@Component注解标记,Spring Boot会自动将每个实例注册为独立的健康指标;同时你又在配置类里把它们加入到CompositeReactiveHealthContributor中,导致健康端点同时加载了独立指标和复合指标,进而出现重复显示、指标被调用两次的情况。
以下两种方案任选其一即可解决:
方案一:移除自定义指标的@Component注解
直接去掉CustomNHealthIndicator上的@Component,让这些指标仅通过复合组件被加载:
- 修改自定义指标类:
// 移除@Component注解 public class CustomNHealthIndicator implements ReactiveHealthIndicator, NamedContributor<ReactiveHealthContributor> { // 如有依赖注入,通过构造函数传入 public CustomNHealthIndicator(/* 依赖参数 */) { // 初始化逻辑 } @Override public Mono<Health> health() { // 原有健康检查逻辑 } @Override public String getName() { return "My name N"; } @Override public ReactiveHealthContributor getContributor() { return this; } }
- 在配置类中手动注册这些指标的Bean,并构建复合组件:
@Configuration public class HealthConfiguration { // 注册各个自定义指标Bean @Bean public CustomHealthIndicator1 customHealthIndicator1() { return new CustomHealthIndicator1(/* 传入所需依赖 */); } @Bean public CustomHealthIndicator2 customHealthIndicator2() { return new CustomHealthIndicator2(/* 传入所需依赖 */); } @Bean public CustomHealthIndicator3 customHealthIndicator3() { return new CustomHealthIndicator3(/* 传入所需依赖 */); } @Bean public CompositeReactiveHealthContributor compositeHealthContributor( CustomHealthIndicator1 customHealthIndicator1, CustomHealthIndicator2 customHealthIndicator2, CustomHealthIndicator3 customHealthIndicator3) { var contributors = Map.of( customHealthIndicator1.getName(), customHealthIndicator1, customHealthIndicator2.getName(), customHealthIndicator2, customHealthIndicator3.getName(), customHealthIndicator3); return CompositeReactiveHealthContributor.fromMap(contributors); } }
方案二:使用@HealthEndpointExclude注解(Spring Boot 2.7+)
如果你需要保留@Component(比如依赖Spring自动注入),可以给自定义指标添加@HealthEndpointExclude注解,阻止Spring将其自动注册为独立健康指标:
@Component @HealthEndpointExclude // 添加此注解,排除自动注册到健康端点 public class CustomNHealthIndicator implements ReactiveHealthIndicator, NamedContributor<ReactiveHealthContributor> { @Override public Mono<Health> health() { // 原有健康检查逻辑 } @Override public String getName() { return "My name N"; } @Override public ReactiveHealthContributor getContributor() { return this; } }
这种方式下,你的原有配置类无需修改,Spring只会将CompositeReactiveHealthContributor注册到健康端点,内部的子指标只会被调用一次。
内容的提问来源于stack exchange,提问作者Julien Charon
相关产品推荐
相关产品推荐

