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

时间:2018-12-20 17:06:24

标签: url kubernetes api-design health-monitoring kubernetes-health-check

我控制着两个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的就绪状态健康检查?

5 个答案:

答案 0 :(得分:4)

参考Microsoft的Implementing Resilient Applications教程。特别是Health monitoring,建议如果当前服务的整体状态取决于依赖项的状态,则仅当其依赖项是健康的时,服务的健康状态才应该是健康的

  

但是,eShopOnContainers的MVC Web应用程序对其余微服务具有多个依赖关系。因此,它为每个微服务调用一个AddUrlCheck方法,如以下示例所示:

// 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"]);
        });
    }
}
  

因此,微服务在所有检查也都正常之前不会提供“健康”状态。

强调我的

因此,要更直接地回答关于

的问题
  

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

我会说应该的。尤其是如果依赖项B的运行状况直接影响A的稳定性。

答案 1 :(得分:3)

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

使用A来检查B的优点是您可以fail fast on a bad rolling upgrade。假设您的A配置错误,因此升级为B提供了错误的连接详细信息-也许B的服务名称已作为环境变量注入,而新版本有错字。如果您的A实例在启动时检查到B,则可以更轻松地确保升级失败,并且没有流量流向配置错误的新Pod。有关更多信息,请参见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,所以A可以到达的任何B实例都将是就绪的。如果B的readiness endpoint performs more checks than the liveness one,则调用B的活动性终结点而不是准备状态可以有所作为。请记住,kubernetes将定期调用这些探针-readiness as well as liveness - they both have a period。区别在于Pod是从服务流量中退出(如果准备就绪失败)还是重新启动(如果活动失败)。您不是要尝试end-to-end transaction checks,而是要使这些检查包含最少的逻辑并且不占用过多的负载。

最好在A的就绪实现中的代码进行检查,而不是在k8s级别(在Pod规范本身中)进行检查。在k8s级别上这样做是第二好,因为理想情况下您想知道容器中运行的代码确实可以连接。

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

请谨慎检查其他服务是否处于就绪状态,因为这可能导致级联的不可用性。例如,如果后端短暂掉线而前端正在对其进行探测,则该前端也将变得不可用,因此将无法显示良好的错误消息。您可能想从简单的探针开始,并在添加过程中仔细添加复杂性。

答案 2 :(得分:1)

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

例如,在启动阶段,服务可能是尚未运行的Bot,因为从属组件/服务尚未运行或尚未就绪。 (例如,DB尚未连接)。 因此,我要说的是,为了准备就绪,您可能需要确保其他必要组件仍然存在或准备就绪。您只需决定哪些是检查准备就绪的必要条件。

答案 3 :(得分:0)

当我在一个应用程序中实现运行状况终结点时,我将按照最佳实践检查该应用程序需要工作的所有依赖项。

如果这些依赖项之一不起作用,则我的应用程序将不起作用,因此将其标记为不正常。

答案 4 :(得分:0)

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