降级健康检查的 HTTP 状态码应该是什么?
What should the HTTP Status Code of a Degraded Health Check Be?
我在 /status
有一个运行状况检查端点 returns 以下状态代码和响应主体:
- 健康 -
200 OK
- 已降级 -
?
- 不健康 -
503 Service Unnavailable
降级响应的 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 似乎适用并符合:
- https://datatracker.ietf.org/doc/draft-inadarei-api-health-check/
- https://www.rfc-editor.org/rfc/rfc7234#section-5.5 尽管已弃用
Warning: 199
-header 可以携带详细信息
- 将
max-age
与 livenessProbe.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"}
我在 /status
有一个运行状况检查端点 returns 以下状态代码和响应主体:
- 健康 -
200 OK
- 已降级 -
?
- 不健康 -
503 Service Unnavailable
降级响应的 HTTP 状态代码应该是什么? 'degraded' 检查用于检查
考虑返回 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 似乎适用并符合:
- https://datatracker.ietf.org/doc/draft-inadarei-api-health-check/
- https://www.rfc-editor.org/rfc/rfc7234#section-5.5 尽管已弃用
Warning: 199
-header 可以携带详细信息 - 将
max-age
与livenessProbe.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"}