Eureka 客户端未反映 OUT_OF_SERVICE 的手动状态
Eureka Client not reflecting manual status of OUT_OF_SERVICE
我有一个使用 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
.
这是预期的吗?我假设尤里卡客户端会知道一个实例是 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
并尝试在刷新缓存之前查询应用程序的发现客户端,客户端和服务器有不同的视图实例。如果我在向客户端询问下一个服务器之前等待 registryRefreshInterval 秒,它会正确地忽略我手动放入 OUT_OF_SERVICE
状态的实例。
我有一个使用 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
.
这是预期的吗?我假设尤里卡客户端会知道一个实例是 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
并尝试在刷新缓存之前查询应用程序的发现客户端,客户端和服务器有不同的视图实例。如果我在向客户端询问下一个服务器之前等待 registryRefreshInterval 秒,它会正确地忽略我手动放入 OUT_OF_SERVICE
状态的实例。