Безотказное поведение клиента Eureka - PullRequest
1 голос
/ 19 июня 2020

Похоже, что следующая задача не имеет единого решения, и я пытаюсь решить ее с другой стороны. Инфраструктура микросервисов состоит из микросервисов Spring Boot с серверами Eureka-Zuul-Config-Admin в качестве службы me sh. Все микросервисы работают внутри Docker контейнеров на платформе Kubernetes. Kubernetes отслеживает проверку работоспособности приложения (проверки работоспособности / готовности) и повторно развертывает ее, когда проверка работоспособности в неактивном состоянии превышает тайм-аут проверки работоспособности.

Проблема в следующем - иногда микросервис не получает правильный адрес сервера Eureka после повторного развертывания. Регистрация обнаружения службы завершается неудачно, но микросервис продолжает работать с проверкой работоспособности 'UP', а зависимые микросервисы пропускают его.

Микрослужбы взаимозависимы, и отказ одного микросервиса вызывает каскадный отказ всех зависимых микросервисов. Я не использую Histrix по некоторым причинам, и на самом деле это не решает мою проблему - пропущенные данные из отказавшего микросервиса просто отключают всю функциональность, связанную с набором зависимых микросервисов.

Вопрос: Можно ли что-то настроить как поведение 'fail-fast' для клиента Eureka без написания настраиваемого HealthIndicator? Проверка работоспособности привода должна находиться в состоянии 'DOWN', в то время как клиент Eureka не получает 204 ответа об успешной регистрации от Eureka.

Вот пример того, как я исправляю это в коде. У него довольно простое поведение - проверка работоспособности отключается «навсегда» после превышения тайм-аута до успешной регистрации в Eureka при запуске и / или во время выполнения. Основная цель состоит в том, что Kubernetes повторно развернет микросервис, когда истечет время ожидания проверки живучести.

@Component
public class CustomHealthIndicator implements HealthIndicator {

    private static final Logger logger = LoggerFactory.getLogger(CustomHealthIndicator.class);

    @Autowired
    @Qualifier("eurekaClient")
    private EurekaClient eurekaClient;

    private static final int HEALTH_CHECK_DOWN_LIMIT_MIN = 15;

    private LocalDateTime healthCheckDownTimeLimit = getHealthCheckDownLimit();

    @Override
    public Health health() {
        int errCode = registeredInEureka();
        return errCode != 0
                ? Health.down().withDetail("Eureka registration fails", errCode).build()
                : Health.up().build();
    }

    private int registeredInEureka() {
        int status = 0;
        if (isStatusUp()) {
            healthCheckDownTimeLimit = getHealthCheckDownLimit();
        } else if (LocalDateTime.now().isAfter(healthCheckDownTimeLimit)) {
            logger.error("Exceeded {} min. limit for getting 'UP' state in Eureka", HEALTH_CHECK_DOWN_LIMIT_MIN);
            status = HttpStatus.GONE.value();
        }
        return status;
    }

    private boolean isStatusUp() {
        return eurekaClient.getInstanceRemoteStatus().compareTo(InstanceInfo.InstanceStatus.UP) == 0;
    }

    private LocalDateTime getHealthCheckDownLimit() {
        return LocalDateTime.now().plus(HEALTH_CHECK_DOWN_LIMIT_MIN, ChronoUnit.MINUTES);
    }
}

Можно ли сделать то же самое, просто настроив компоненты Spring?

...