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

What should the HTTP Status Code of a Degraded Health Check Be?

我在 /status 有一个运行状况检查端点 returns 以下状态代码和响应主体:

降级响应的 HTTP 状态代码应该是什么? 'degraded' 检查用于检查 。什么 HTTP 状态代码最有意义?

考虑返回 2xx Success 范围内的自定义代码,该代码尚未在 known/common 状态代码内使用。类似于一些不被任何标准支持的unofficial codes

例如218 This is fine (Apache Web Server)

Used as a catch-all error condition for allowing response bodies to flow through Apache when ProxyErrorOverride is enabled. When ProxyErrorOverride is enabled in Apache, response bodies that contain a status code of 4xx or 5xx are automatically discarded by Apache in favor of a generic response or a custom response specified by the ErrorDocument directive

经过一些研究,我发现了一个草稿

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

他们也提出了类似的建议

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,我认为这与您想要的模型非常吻合。

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

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

我通常使用以下界面进行应用程序健康检查:

204 - No Content, everything is working within tolerences

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

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

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

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

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

之所以这样说,是因为我在官方Hypertext Transfer Protocol (HTTP) Status Code Registry maintained by IANA, pointed to by [RFC7231] HTTP/1.1: Semantics and Content中找不到更好的代码。应避免使用非官方代码,因为它们只会让您的 API 更难理解。

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

对您的设计的其他评论

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

因此,对 GET /status 请求的 503 Service Unavailable 响应意味着 状态检查操作本身 失败。只有当我们可以确定 /status 健康内在 时,这样的回应才有用,正如 Nkosi 的回答中提到的 API Health Check draft 中指出的那样:

A health endpoint is only meaningful in the context of the component it indicates the health of. It has no other meaning or purpose. As such, its health is a conduit to the health of the component. Clients SHOULD assume that the HTTP response code returned by the health endpoint is applicable to the entire component (e.g. a larger API or a microservice).

但是 URL 路径只有 /status,这并不完全明显 健康端点。通过查看 URL,我们只知道它 returns 有关某物状态的信息,但我们无法真正确定该“某物”是什么。

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

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

所以要小心命名事物的方式和使用的状态代码!

假设您指的是服务的 liveness/healthcheck 端点的状态代码 - 以区别于 200 OK a 203 似乎适用并符合:

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"}