我有一个管理应用程序,它使用 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
:
但是,CloudEurekaClient
似乎不知道实例是 OUT_OF_SERVICE
。相反,使用调试器,我发现该实例的状态为 UP
并覆盖UNKNOWN
的状态:
注意:如果我调用cloudEurekaClient.getApplication("worker").getInstances()
它显示 4 UP
实例,但没有提及OUT_OF_SERVICE
.
这是预期的吗?我假设 eureka 客户端知道实例是 OUT_OF_SERVICE
,但这不是我看到的行为。这会导致我使用 CloudEurekaClient
的运行状况指示器出现问题。显示 UP
的数量和OUT_OF_SERVICE
实例。
最佳答案
经过一番挖掘,问题似乎是设置实例状态会立即调用 Eureka 服务器,这就是服务器状态 UI 实时显示正确状态的原因:
public void setStatus(InstanceStatus newStatus, InstanceInfo info) {
getEurekaHttpClient().statusUpdate(info.getAppName(), info.getId(), newStatus, info);
}
但是,调用CloudEurekaServer.getNextServerFromEureka()
使用本地缓存,该缓存仅在计时器上定期更新,该计时器由 EurekaClientConfig.getRegistryFetchIntervalSeconds()
定义。 .
所以我处于竞争状态,如果我将实例状态设置为 OUT_OF_SERVICE
并尝试在刷新缓存之前向发现客户端查询应用程序,客户端和服务器对实例具有不同的 View 。如果我在向客户端请求下一个服务器之前等待 registryRefreshInterval 秒,它会正确忽略我手动放入 OUT_OF_SERVICE
的实例。状态。
关于spring-cloud - Eureka 客户端未反射(reflect) OUT_OF_SERVICE 的手动状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52173779/