我有一个使用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
,而overridenStatus的状态为UNKNOWN
:
注意:如果我调用cloudEurekaClient.getApplication("worker").getInstances()
,它将显示4个UP
实例,但没有提及OUT_OF_SERVICE
实例。
这是预期的吗?我以为eureka客户知道实例是OUT_OF_SERVICE
,但这不是我所看到的行为。这会给我使用CloudEurekaClient
来显示UP
和OUT_OF_SERVICE
实例数的运行状况指示器带来问题。
答案 0 :(得分:0)
经过一番挖掘,问题似乎在于设置实例状态立即调用Eureka Server,这就是服务器状态UI实时显示正确状态的原因:
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
状态的实例。