Spring执行器-服务发现-/health"description":"Discovery Client not initialized","status":"UNKNOWN"

Spring Actuator - Service discovery - /health "description":"Discovery Client not initialized","status":"UNKNOWN"

与 Spring Boot Actuator 的服务发现相关的问题,请结合 Spring Cloud Kubernetes。

目前,我有一个 Web 应用程序,它同时具有执行器和 spring 引导 kubernetes 依赖项。 我也在使用 kubernetes 提供的发现客户端,一切正常。

但是,当我卷曲我的健康端点时,我确实看到了那些奇怪的陈述:

discoveryComposite":{"description":"Discovery Client not initialized","status":"UNKNOWN","components":{"discoveryClient":{"description":"Discovery Client not initialized","status":"UNKNOWN"}}

"reactiveDiscoveryClients":{"description":"Discovery Client not initialized","status":"UNKNOWN","components":{"Kubernetes Reactive Discovery Client":{"description":"Discovery Client not initialized","status":"UNKNOWN"}

Simple Reactive Discovery Client":{"description":"Discovery Client not initialized","status":"UNKNOWN"}}}

"readinessState":{"status":"UP"},"refreshScope":{"status":"UP"}},"groups":["liveness","readiness"]}*

请问为什么是“未知”?我本以为这里的三个中至少有一个是怎么回事,绝对不是“发现客户端未初始化”。

我是不是忘了初始化什么?注册什么?要配置什么?

顺便说一句,这确实是一个关于使用 kubernetes 进行发现的问题。与 Eureka 无关,与 Consul 等无关。

非常感谢

遇到同样的问题,我注意到 org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicatordiscoveryInitialized 字段设置为 false。这是因为没有人在应用程序上下文中触发 InstanceRegisteredEvent。通常事件应该从所谓的“注册”的 start() 方法触发 - 一个负责在服务注册表中注册当前应用程序实例的 bean,例如EurekaAutoServiceRegistration 在尤里卡的情况下。

关键是 Kubernetes 本身不是服务注册中心,它不需要显式注册(因为由于编排的性质,其中的每个 pod 默认情况下都是“注册”的)。这就是为什么 Spring Cloud Kubernetes 默认情况下不向 Kubernetes 注册应用程序实例。

但是 org.springframework.cloud.kubernetes.registry.KubernetesAutoServiceRegistration class 可以通过简单地向日志发送消息来“模拟”自动注册的过程。从 v1.1.0 开始,这个 class 是 @Deprecated 并且在其他地方的框架中没有使用。目前我看到使用它的唯一好处是它可以触发丢失的 InstanceRegisteredEvent 来初始化 DiscoveryClientHealthIndicator。您可以通过将以下 bean 声明添加到任何 @Configuration classes:

来使用它
@Bean
public KubernetesAutoServiceRegistration kubernetesAutoServiceRegistration(
         ApplicationContext context, 
         KubernetesServiceRegistry registry,
         KubernetesRegistration registration) {
  return new KubernetesAutoServiceRegistration(context, registry, registration);
}

但是请不要过度依赖它,因为它可能会在即将发布的框架版本中被删除。

作为替代方案,您可以自己在代码中的某处发出 InstanceRegisteredEvent,但请确保在应用程序实际准备好与发现客户端一起工作时执行此操作。