0

我正在尝试配置执行器的运行状况探测,以包括对嵌套在第一级之外的外部服务的检查。例如,当调用 /actuator/health 时,这些是可用的健康指标:

    {
       "status":"DOWN",
       "components":{
          "jms":{
             "status":"DOWN",
             "components":{
                "broker1":{
                   "status":"DOWN",
                   "details":{
                      "error":"javax.jms.JMSException: Failed to create session factory"
                   }
                },
                "broker2":{
                   "status":"UP",
                   "details":{
                      "provider":"ActiveMQ"
                   }
                }
             }
          },
          "livenessState":{
             "status":"UP"
          },
          "readinessState":{
             "status":"UP"
          }
       },
       "groups":[
          "liveness",
          "readiness"
       ]
    }

jms组件下,有两个代理 - broker1broker2。我可以将 Actuator 配置为将jms包含在准备组中,例如:

  endpoint:
    health:
      probes:
        enabled: true
      enabled: true
      show-details: always
      group:
        readiness:
          include: readinessState, jms

但是,这将包括准备调查中的所有经纪人。

调用 /actuator/health/readiness 时,我得到:

{
   "status":"DOWN",
   "components":{
      "jms":{
         "status":"DOWN",
         "components":{
            "broker1":{
               "status":"DOWN",
               "details":{
                  "error":"javax.jms.JMSException: Failed to create session factory"
               }
            },
            "broker2":{
               "status":"UP",
               "details":{
                  "provider":"ActiveMQ"
               }
            }
         }
      },
      "readinessState":{
         "status":"UP"
      }
   }
}

由于 Kubernetes 中的就绪探测只会阻止将 Web 请求路由到我的 pod,因此我有一些情况,如果broker1关闭,只要broker2启动,我就可以处理请求。有没有办法将执行器配置为在健康组中包含嵌套的健康指标,而不仅仅是根指标?我尝试了 broker1、jms.broker1、jms/broker1、jms\broker1 等组合,但无济于事。

如果不直接通过配置支持,是否有我可以创建的自定义组件会给我所需的行为。例如,我想到了编写自定义 CompositeHealthContributor 的可能性,但我不确定是否可以聚合现有的健康指标。我不想复制已经完成的健康检查。

另一个相关用例是只要一组外部资源中的一个可用,就认为服务是健康的。例如,我在两个数据中心有一个相同的代理。只要其中一位经纪人可用,那么我的服务就可以被认为是健康的。对于这个用例,什么是好的方法?

4

1 回答 1

0

我相信只要将嵌套指标暴露为Health对象,就会得到想要的结果:

@Component
public class CustomHealthIndicator implements ReactiveHealthIndicator {

    private final List<CustomContributor> customContributors;

    public CustomHealthIndicator(List<CustomContributor> customContributors) {
        Assert.notNull(customContributors, "At least one contributor must be available");
        this.customContributors = customContributors;
    }

    @Override
    public Mono<Health> health() {
        return checkServices()
            .onErrorResume(ex -> Mono.just(new Health.Builder().down(ex).build()));
    }

    private Mono<Health> checkServices() {
        return Mono.fromSupplier(() -> {
            final Builder builder = new Builder();
            AtomicBoolean partial = new AtomicBoolean();
            this.customContributors.parallelStream()
                .forEach(customContributor -> {
                    final Object status = customContributor.getStatus();
                    final boolean isAnErrorState = status instanceof Throwable;
                    partial.set(partial.get() || isAnErrorState);

                    if(isAnErrorState){
                        builder.withDetail(customContributor.getName(), new Builder().down().withException((Throwable) status).build());
                    } else {
                        builder.withDetail(customContributor.getName(), new Builder().up().withDetail("serviceDetail", status).build());
                    }
                });
            builder.status(partial.get() ? Status.DOWN : Status.UP);
            return
                builder.build();
        });
    }
}
于 2021-10-10T20:19:10.233 回答