降级健康检查的 HTTP 状态码应该是啥?

Posted

技术标签:

【中文标题】降级健康检查的 HTTP 状态码应该是啥?【英文标题】:What should the HTTP Status Code of a Degraded Health Check Be?降级健康检查的 HTTP 状态码应该是什么? 【发布时间】:2019-05-27 20:36:47 【问题描述】:

我在/status 有一个运行状况检查端点,它返回以下状态代码和响应正文:

健康 - 200 OK 降级 - ? 不健康 - 503 Service Unnavailable

对于降级响应的 HTTP 状态代码应该是什么? “降级”检查用于did succeed but are slow or unstable 的检查。什么 HTTP 状态代码最有意义?

【问题讨论】:

我认为你的问题没有意义。您需要决定 HTTP GET/status 应该做什么 您认为您的选择是什么?如果它正常工作,我们使用 200 并在必要时返回附加信息。真的,这取决于你。 @MuhammadRehanSaeed 返回一个自定义代码,其 2xx 成功范围尚未采用已知/常用代码。类似于一些不受任何标准支持的unofficial codes。例如218 This is fine (Apache Web Server) @MuhammadRehanSaeed 还发现了这个tools.ietf.org/html/draft-inadarei-api-health-check-00 @MuhammadRehanSaeed 希望您检查更多recent version 他们还建议In case of the “warn” status, endpoints MUST return HTTP status in the 2xx-3xx range, and additional information SHOULD be provided, utilizing optional fields of the response. 其中warn 状态为healthy, with some concerns,我相信这与您的模式密切相关。 【参考方案1】:

假设您指的是服务的活动/健康检查端点的状态代码 - 与 200 OK 区分开来,一个 203 似乎适用且符合要求与:

https://datatracker.ietf.org/doc/draft-inadarei-api-health-check/ https://www.rfc-editor.org/rfc/rfc7234#section-5.5 尽管已被弃用 Warning: 199-header 可能会携带详细信息 将max-agelivenessProbe.periodSeconds 对齐
HTTP/1.1 203 Non-Authoritative Information
Warning: 199 - "FooBar Warning Details"
Content-Type: application/health+json
Cache-Control: max-age=10
Connection: close

"status": "warn"

【讨论】:

【参考方案2】:

对于来自健康端点的“降级”状态响应,最合适的 HTTP 状态代码就是 200 OK

我这样说是因为我在 IANA 维护的官方 Hypertext Transfer Protocol (HTTP) Status Code Registry 中找不到更好的代码,[RFC7231] HTTP/1.1: Semantics and Content 指出了这一点。应避免使用非官方代码,因为它们只会使您的 API 更难理解。

您应该设计您的 API,使其易于使用。资源名称、HTTP 动词、状态代码等应该或多或少是不言自明的,这样已经了解“REST 语言”的人可以立即了解如何使用您的 API,而无需破译模糊的名称或不寻常的状态代码。这使我进入了答案的下一部分......

您设计中的其他 cmets

解释对任何请求的5xx 响应的最自然方式是相关操作失败。

所以503 Service UnavailableGET /status 请求的响应意味着状态检查操作本身失败。只有当我们可以确定 /status 是一个 health endoint 时,这样的响应才会有用,正如 Nkosi 的回答中提到的 API Health Check draft 中所指出的那样:

健康端点仅在组件的上下文中才有意义 它预示着健康。它没有其他意义或目的。作为 因此,它的健康状况是组件健康状况的管道。 客户端应该假设客户端返回的 HTTP 响应代码 健康端点适用于整个组件(例如更大的 API 或微服务)。

但是对于只有/status 的 URL 路径,这并不是很明显一个健康端点。通过查看 URL,我们只知道它返回了有关某物状态的信息,但我们无法确定该“某物”是什么。

既然您也告诉我们是的,它实际上是一个健康端点,我必须建议您将名称更改为health。我还建议将它放在一些基本路径下,例如/things/health,以便更清楚地表明哪个组件的健康状况。

另一方面,如果/status 实际上是它自己的资源,即代表某些other 组件/事物状态的东西(就像它目前的名字所暗示的那样),那么@ 987654333@ 是成功调用的唯一合理状态,即使它指示的状态是“不健康”。在这种情况下,5xx 意味着无法获取任何状态,并且会假定响应负载中的详细信息与/status 服务本身的故障有关。

所以要小心你如何命名事物以及你使用什么状态码!

【讨论】:

【参考方案3】:

我会警惕在上游服务器端的健康检查中像这样分裂头发。提供健康检查的服务应该根据自己的一套策略或规则(请求超时、连接失败等)轻轻(并同时)测试其所有上游依赖项。实际上,运行状况检查要么起作用,要么不起作用,并且应用程序实际上不需要跟踪运行状况检查的结果(除了捕获有关所发生情况的指标)。恕我直言,有状态的健康检查是灾难的根源。

我通常使用以下接口进行应用程序运行状况检查:

204 - No Content, everything is working within tolerences

500 - Something failed, and here's some details in the response about what went wrong

棘手的地方取决于您的架构。您可能有一个 VIP 或反向代理来解释此响应并确定给定节点是否健康,在这种情况下,它会将请求路由到健康节点或返回 503 Service Unavailable。该决定将基于某些策略做出 - x 个健康检查请求在 y 时间段内跨 z 个上游服务失败。

如果您使用网格,那么每个人都可以将数据反馈到服务注册表以保持健康状态为最新状态,并且它可以基于实际的服务调用而不是健康检查。

客户端完全可以根据它所依赖的服务的健康状况做出决定,因为他们可以跟踪来自服务的各种响应。断路器是处理该问题的绝佳方式,并且可以根据实际请求连续进行,而不仅仅是在运行状况检查上。断路器库(例如resilience4j)将为您执行此操作,但代价是设置一些关于有多少失败/慢速请求构成不良服务的策略。像 netflix eureka 这样的服务注册可以帮助发现和持续监控。

【讨论】:

【参考方案4】:

考虑在 2xx 成功 范围内返回一个尚未在已知/常见状态代码中采用的自定义代码。类似于一些不受任何标准支持的unofficial codes。

例如218 This is fine (Apache Web Server)

当启用 ProxyErrorOverride 时,用作允许响应主体流经 Apache 的包罗万象的错误条件。在 Apache 中启用 ProxyErrorOverride 时,Apache 会自动丢弃包含 4xx 或 5xx 状态代码的响应正文,以支持通用响应或由 ErrorDocument 指令指定的自定义响应

在做了一些研究后,我发现了一个草稿

Health Check Response Format for HTTP APIs: draft-inadarei-api-health-check-03

他们也提出了类似的建议

在“警告”状态的情况下,端点必须返回 2xx-3xx 范围内的 HTTP 状态,并且应该使用响应的可选字段提供附加信息。

草稿中的warn 状态为healthy, with some concerns,我认为这与您想要的模型非常吻合。

虽然不是确定的,但我相信它提供了一些有助于最终设计的想法。

【讨论】:

我通过 Twitter 联系了草稿的作者(参见 twitter.com/RehanSaeedUK/status/1081121474667253760?s=20)。他的回答基本上是参考 HTTP RFC(没有多大帮助)并避免使用非官方的状态代码。虽然不是完整的答案,但您的意见很有价值,非常感谢!

以上是关于降级健康检查的 HTTP 状态码应该是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取 Azure APIM 健康检查和详细信息

LVS+Keepalived 高可用群集(DR模式)

Nginx实战|Nginx健康检查

健康检查的最佳做法是啥?

Systemd http 健康检查

LVS集群RS健康状态检查