Похоже, что следующая задача не имеет единого решения, и я пытаюсь решить ее с другой стороны. Инфраструктура микросервисов состоит из микросервисов 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?