Spring Actuator - 服务发现 - /health“描述”:“发现客户端未初始化”,“状态”:“未知”

Pat*_*Pat 2 java spring-boot-actuator spring-cloud-kubernetes

有关使用 Spring Boot Actuator 进行服务发现的问题,请结合 Spring Cloud Kubernetes。

目前,我有一个 Web 应用程序,它同时具有执行器和 Spring Boot 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"]}*
Run Code Online (Sandbox Code Playgroud)

请问为什么是“未知”?我预计这里的三个中至少有一个会出现问题,并且绝对不是“发现客户端未初始化”。

我是否忘记初始化某些东西?注册一些东西?配置一些东西?

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

非常感谢

Top*_*ion 6

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

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

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

@Bean
public KubernetesAutoServiceRegistration kubernetesAutoServiceRegistration(
         ApplicationContext context, 
         KubernetesServiceRegistry registry,
         KubernetesRegistration registration) {
  return new KubernetesAutoServiceRegistration(context, registry, registration);
}
Run Code Online (Sandbox Code Playgroud)

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

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