skip to Main Content

Service health check api response 503 when redis is down.

{
    "status": "DOWN",
    "details": {
        "diskSpace": {
            "status": "UP",
            "details": {
                "total": 250790436864,
                "free": 95412813824,
                "threshold": 10485760
            }
        },
        "db": {
            "status": "UP",
            "details": {
                "database": "PostgreSQL",
                "hello": 1
            }
        },
        "refreshScope": {
            "status": "UP"
        },
        "redis": {
            "status": "DOWN",
            "details": {
                "error": "org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379"
            }
        }
    }
}

But actually service is available when redis is down.

Could service status not be effected by redis status ? and I also need see the redis detail in health check api.

3

Answers


  1. I usually check https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html this to find something like what you are doing

    and there I found management.health.redis.enabled (default true)
    so my guess would be if you explicitly set this to false it would disappear from your healthcheck

    Login or Signup to reply.
  2. management.health.redis.enabled=false

    Add this code to disable the Redis health check in your application.yaml/properties

    Login or Signup to reply.
  3. We solved this issue by overriding getAggregateStatus of SimpleStatusAggregator so that the redis status is shown in the details, but no influence in the aggregated status.

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.actuate.health.*;
    import org.springframework.boot.actuate.redis.RedisHealthIndicator;
    import org.springframework.stereotype.Component;
    
    import java.util.List;
    import java.util.Set;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    import java.util.stream.StreamSupport;
    
    import static java.util.Collections.singletonList;
    import static java.util.function.Predicate.not;
    import static java.util.stream.Collectors.toList;
    
    
    @Component
    public class CustomStatusAggregator extends SimpleStatusAggregator {
    
        @Autowired
        private List<HealthContributor> healthContributorList;
    
           
        @Override
        public Status getAggregateStatus(Set<Status> statuses) {
            return super.getAggregateStatus(getStatuses());
        }
    
        private Set<Status> getStatuses() {
            Stream<Status> statuses = healthContributorList //
                    .stream() //
                    .map(CustomStatusAggregator::getHealthIndicators) //
                    .flatMap(List<HealthIndicator>::stream) //
                    .filter(not(RedisHealthIndicator.class::isInstance)) //
                    .map(HealthIndicator::health) //
                    .map(Health::getStatus);
    
            return statuses.collect(Collectors.toSet());
        }
    
        private static List<HealthIndicator> getHealthIndicators(HealthContributor healthContributor) {
            if (healthContributor instanceof HealthIndicator) {
                return singletonList(((HealthIndicator) healthContributor));
            }
    
            return stream((CompositeHealthContributor) healthContributor) //
                    .map(NamedContributor::getContributor) //
                    .map(CustomStatusAggregator::getHealthIndicators) //
                    .flatMap(List<HealthIndicator>::stream) //
                    .collect(toList());
        }
    
        private static <T> Stream<T> stream(Iterable<T> iterable) {
            return StreamSupport.stream(iterable.spliterator(), false);
        }
    
    }
    

    If you have a combination of ReactiveHealthContributor and HealthContributor, you can combine the status

    @Autowired
    private List<ReactiveHealthContributor> reactiveHealthContributorList;
    
    return Stream.concat(statuses, reactiveStatuses).collect(Collectors.toSet());
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search