spring-attic / spring-cloud-gcp

Integration for Google Cloud Platform APIs with Spring
Apache License 2.0
704 stars 694 forks source link

Spring Cloud Stream doesn't see a health indicator for Pub/Sub and therefore report it as UNKNOWN. #2631

Open VladimirMarinkovic opened 3 years ago

VladimirMarinkovic commented 3 years ago

Common health indicator is not enough for Spring Cloud Stream

When I getting health from spring actuator, response is: components": { "binders": {"status": "UNKNOWN", "components": {"pubsub": {"status": "UNKNOWN"}}}


The part from my config yaml.

spring:
  cloud:
    stream:
      binders:
        pubsub:
          inherit-environment: false
          default-candidate: true
      bindings:
        output:
          binder: pubsub
          destination: example-destination
          group: example-group
      default-binder: pubsub

management:
  health:
    status:
      order: DOWN,OUT_OF_SERVICE,UNKNOWN,DEGRADED,UP
  endpoints:
    web:
      base-path: /actuator
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: always

The part from my pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-gcp-pubsub-stream-binder</artifactId>
    <version>1.2.6.RELEASE</version>
</dependency>
artembilan commented 3 years ago

This is related to: https://github.com/spring-cloud/spring-cloud-gcp/issues/2030.

I think what we have missed there is this:

@meltsufin I'll submit a much smaller PR for a PubSubHealthIndicator not binder specific, will follow up with one for the binders as it will require changes to the PubSubBinder too

Probably every single binder @Configuration should have its own HealthIndicator bean definition, then Spring Cloud Stream can identify it properly from binderContext.

elefeint commented 3 years ago

@VladimirMarinkovic Is UNKNOWN bad, or merely surprising in your usecase? As it happens, there is no useful per-subscription information we can provide, so the global Pub/Sub status already gives all possible information about Pub/Sub connection health.

@artembilan Pub/Sub is similar to Rabbit configuration in that there is only a global verifiable state. I've tested what it would look like to provide a binder-scoped HealthIndicator, similar to what Rabbit does, and it works. But that results in two identical PubSubHealthIndicator beans doing the same thing at the same time for, really, zero additional information (we know "pubsub is up" from the non-binder-specific check). Is there a way to tell Spring Cloud Stream to reuse the existing global health check bean instead of duplicating the configuration?

{
   "status":"UP",
   "components":{
      "binders":{
         "status":"UP",
         "components":{
            "pubsub":{
               "status":"UP"
            }
         }
      },
     ...
      "pubSub":{
         "status":"UP"
      }
   }
}
artembilan commented 3 years ago

@elefeint ,

your observation is correct: there won't be difference between global Pub/Sub health and form binder one. At least at the moment. Probably later we will come up with something like health for the topics used in the binder.

Unfortunately every binder is spawned in its own ApplicationContext based on the @Configuration class where binder bean is declared. Exactly that application context has to be its own health indicator like you notices in the RabbitMQ one. On the other hand we may have several Pub/Sub binders in the same application: one a source of data from one account and the other to ingest that data into another account. So, that's where we would like to have two of those binder in their own application context with their own environment. And that's actually where their individual health indicators come handy. And that's why every binder configuration in other implementations have those HealthIndicator beans. Although this is not all: those configs even specify an import for service auto-configuration. This way every binder in the application could read its own configuration properties and be separate from other similar.

See docs for more info: https://docs.spring.io/spring-cloud-stream/docs/3.1.0/reference/html/spring-cloud-stream.html#multiple-binders https://docs.spring.io/spring-cloud-stream/docs/3.1.0/reference/html/spring-cloud-stream.html#_health_indicator