健康检查是否应该调用其他应用程序健康检查

Should Health Checks call other App Health Checks

我控制了两个 API 的 A 和 B,并且都进行了就绪和活跃度健康检查。 A 依赖于 B.

A
/foo - This endpoint makes a call to /bar in B
/status/live
/status/ready

B
/bar
/status/live
/status/ready

由于依赖关系,A 的就绪健康检查是否应该调用 API B 的就绪健康检查?

如果服务 A 可以满足业务请求,则它已准备就绪。因此,如果能够到达 B 是它 需要 做的事情的一部分(看起来确实如此),那么它应该检查 B。

让 A 检查 B 的一个好处是你可以 fail fast on a bad rolling upgrade. Say your A gets misconfigured so that the upgrade features a wrong connection detail for B - maybe B's service name is injected as an environment variable and the new version has a typo. If your A instances check to Bs on startup then you can more easily ensure that the upgrade fails and that no traffic goes to the new misconfigured Pods. For more on this see https://medium.com/spire-labs/utilizing-kubernetes-liveness-and-readiness-probes-to-automatically-recover-from-failure-2fe0314f2b2e

通常,A 检查 B 的活动端点或任何最低可用性端点而不是 B 的就绪端点就足够了。这是因为 kubernetes 将 checking B's readiness probe for you anyway so any B instance that A can reach will be a ready one. Calling B's liveness endpoint rather than readiness can make a difference if B's readiness endpoint performs more checks than the liveness one. Keep in mind that kubernetes will be calling these probes regularly - readiness as well as liveness - they both have a period. The difference is whether the Pod is withdrawn from serving traffic (if readiness fails) or restarted (if liveness fails). You're not trying to do end-to-end transaction checks,您希望这些检查包含最少的逻辑并且不会占用太多负载。

最好是 A 的就绪实现中的代码进行检查而不是在 k8s 级别(在 Pod 规范本身中)进行检查。在 k8s 级别进行它是次佳的,因为理想情况下你想知道容器中的代码 运行ning 确实连接。

另一种检查依赖服务的方法可用is with a check in an initContainer。使用 initContainers 可以避免在启动期间看到多次重启(通过确保正确的顺序),但通过探测器对依赖项进行检查可以更深入(如果在应用程序代码中实现)并且探测器将在启动后定期 运行 继续。因此,同时使用两者可能是有利的。

小心检查其他服务是否准备就绪,因为它可能导致级联不可用。例如,如果一个后端短暂地宕机,而一个前端正在探测它,那么前端也将变得不可用,因此将无法显示一个好的错误消息。您可能希望从简单的探测开始,然后小心地增加复杂性。

参考微软的Implementing Resilient Applications tutorials. Specifically the Health monitoring,建议如果当前服务的整体状态依赖于一个依赖的状态,那么只有当它的依赖是健康的时候,服务的健康状态才应该是健康的

However, the MVC web application of eShopOnContainers has multiple dependencies on the rest of the microservices. Therefore, it calls one AddUrlCheck method for each microservice, as shown in the following example:

// Startup.cs from the MVC web app
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.Configure<AppSettings>(Configuration);
        services.AddHealthChecks(checks =>
        {
            checks.AddUrlCheck(Configuration["CatalogUrl"]);
            checks.AddUrlCheck(Configuration["OrderingUrl"]);
            checks.AddUrlCheck(Configuration["BasketUrl"]);
            checks.AddUrlCheck(Configuration["IdentityUrl"]);
        });
    }
}

Thus, a microservice will not provide a “healthy” status until all its checks are healthy as well.

强调我的

所以为了更直接地回答你关于

的问题

Should the readiness health check for A make a call to the readiness health check for API B because of the dependency?

我会说是的。特别是如果依赖 B 的健康直接影响 A 的稳定性。

当我在一个应用程序中实现健康端点时,我遵循最佳实践来检查应用程序工作所需的所有依赖项。

如果这些依赖项之一不起作用,我的应用程序将无法运行,因此它被标记为不健康。

不,您不需要在其他微服务上检查 healthchek。单个微服务应该与其他微服务无关(根据微服务定义)。如果一个微服务依赖于另一个微服务,那么您可以针对其他微服务使用回退、断路器模式,这样它就可以正常工作。

有准备和活力。我认为没有明显的答案。只是一个准则 -
活着意味着服务只是响应。例如能够以 200/OK 响应。 就绪意味着按照预期的方式运行。 (最常用API)

例如,在启动阶段,服务可能处于活动状态但尚未准备就绪,因为依赖 components/services 尚未处于活动状态或准备就绪。 (例如,数据库尚未连接)。 因此,我会说是的,为了准备就绪,您可能需要确保其他基本组件处于活动状态或也已准备就绪。您所要做的就是决定哪些是要检查是否准备就绪的必需品。