Eureka Client не отражает ручной статус OUT_OF_SERVICE - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть приложение-менеджер, которое использует Eureka для обнаружения рабочих приложений. Оба используют Spring Cloud Netflix и автоматические конфигурации, которые они предоставляют, для регистрации и обнаружения сервисов.

Иногда менеджер помечает экземпляр как OUT_OF_SERVICE, а через некоторое время (порядка минут) помечает тот же экземпляр как UP.

Менеджер обнаруживает экземпляры, используя CloudEurekaClient, а затем устанавливает свой статус:

@Autowired
private CloudEurekaClient cloudEurekaClient;

...

InstanceInfo instance = cloudEurekaClient.getNextServerFromEureka(WORKER_SERVICE_NAME, false);
cloudEurekaClient.setStatus(InstanceInfo.InstanceStatus.OUT_OF_SERVICE, instance);
// do some work
cloudEurekaClient.setStatus(InstanceInfo.InstanceStatus.UP, instance);

Кажется, это работает хорошо. На странице состояния сервера Eureka отображаются мои экземпляры с UP до OUT_OF_SERVICE:

enter image description here

Однако CloudEurekaClient, похоже, не знает, что экземпляр является OUT_OF_SERVICE. Вместо этого, используя отладчик, я обнаружил, что экземпляр имеет статус UP и значение overridenStatus UNKNOWN:

enter image description here

Примечание: если я позвоню cloudEurekaClient.getApplication("worker").getInstances(), он покажет 4 UP экземпляров, но не упомянет тот, который OUT_OF_SERVICE.

Ожидается ли это? Я предполагал, что клиент eureka будет знать, что экземпляр OUT_OF_SERVICE, но это не то поведение, которое я вижу. Это вызывает проблемы для моего индикатора работоспособности, который использует CloudEurekaClient для отображения количества UP и OUT_OF_SERVICE экземпляров.

1 Ответ

0 голосов
/ 05 сентября 2018

После некоторого копания проблема, по-видимому, заключается в том, что параметр установки состояния немедленно вызывает Eureka Server, поэтому пользовательский интерфейс состояния сервера отображает правильное состояние в реальном времени:

public void setStatus(InstanceStatus newStatus, InstanceInfo info) {
    getEurekaHttpClient().statusUpdate(info.getAppName(), info.getId(), newStatus, info);
}

Однако при вызове CloudEurekaServer.getNextServerFromEureka() используется локальный кеш, который периодически обновляется только по таймеру, который определяется EurekaClientConfig.getRegistryFetchIntervalSeconds().

Так что я нахожусь в состоянии состязания, когда, если я установлю состояние экземпляра на OUT_OF_SERVICE и попытаюсь запросить у клиента обнаружения приложение до обновления кэша, клиент и сервер будут иметь разные представления об экземплярах. Если я жду registryRefreshInterval секунд, прежде чем запрашивать у клиента следующий сервер, он корректно игнорирует экземпляр, который я вручную перевел в OUT_OF_SERVICE состояние.

...