菜单

健康检查

相关源文件

此页面详细介绍了 Caddy 反向代理处理程序的健康检查功能。健康检查监控上游后端服务器,以确定它们是否可用并正常工作。Caddy 支持主动健康检查(主动探测后端)和被动健康检查(监控实际请求流量)。有关上游之间负载平衡的信息,请参阅 负载平衡

概述

Caddy 的反向代理健康检查机制允许您自动检测并避开故障或过载的上游服务器。健康检查与负载平衡系统交互,以确保请求仅发送到可用的后端。

来源: modules/caddyhttp/reverseproxy/reverseproxy.go85-91 modules/caddyhttp/reverseproxy/reverseproxy.go192-194 modules/caddyhttp/reverseproxy/reverseproxy.go356-374

健康检查类型

主动健康检查

主动健康检查在后台定时运行,并主动向上游服务器发送 HTTP 请求以验证其状态。它们是按代理处理程序配置的,因此不同的处理程序可以对“健康后端”有不同的标准。

来源: modules/caddyhttp/reverseproxy/healthchecks.go272-294 modules/caddyhttp/reverseproxy/healthchecks.go386-581

主动健康检查遵循以下原则

  1. 它们以可配置的间隔定期运行
  2. 每次检查都会向上游发送 HTTP 请求
  3. 上游服务器在以下情况下被视为健康
    • 响应状态码符合预期(默认:2xx)
    • 响应正文与指定的模式匹配(如果已配置)
    • 连接成功
  4. 健康状态阈值
    • 需要连续通过可配置的次数才能将服务器标记为健康
    • 需要连续失败可配置的次数才能将服务器标记为不健康

主动健康检查的关键配置参数

参数描述默认
uri健康检查请求的 URI 路径(和查询)无(必需)
port健康检查的备用端口(如果与上游端口不同)与上游相同
interval执行检查的频率30秒
timeout等待响应的最长时间5秒
headers健康检查请求的自定义 HTTP 请求头
method要使用的 HTTP 方法GET
body要发送的请求体
passes标记为健康所需的连续通过次数1
fails标记为不健康所需的连续失败次数1
expect_status预期的 HTTP 状态码任意 2xx 状态码
expect_body用于匹配响应体的正则表达式
follow_redirects健康检查中是否跟踪重定向

来源: modules/caddyhttp/reverseproxy/healthchecks.go74-135 modules/caddyhttp/reverseproxy/caddyfile.go335-547

被动健康检查

被动健康检查监控向上游服务器发送的实际请求流量并检测故障。与主动检查不同,被动健康检查是全局跟踪的,并在所有代理处理程序之间共享。

来源: modules/caddyhttp/reverseproxy/reverseproxy.go583-640 modules/caddyhttp/reverseproxy/reverseproxy.go916-928

被动健康检查遵循以下原则

  1. 它们监控实际生产流量
  2. 故障在可配置的持续时间内被计数
  3. 上游服务器在以下情况下被视为不健康
    • 它返回指定的 HTTP 错误状态码
    • 它超过了配置的延迟阈值
    • 它有太多的并发请求
  4. 故障计数在配置的故障持续时间后自动重置

被动健康检查的关键配置参数

参数描述默认
fail_duration记住失败请求的时长0 (禁用)
max_fails将后端视为宕机的失败次数1
unhealthy_request_count标记为宕机前的最大并发请求数0 (无限制)
unhealthy_status计为失败的 HTTP 状态码
unhealthy_latency计为失败的响应时间阈值0 (禁用)

来源: modules/caddyhttp/reverseproxy/healthchecks.go234-257 modules/caddyhttp/reverseproxy/caddyfile.go549-633

健康检查集成

健康检查系统与反向代理的其他组件集成如下

来源: modules/caddyhttp/reverseproxy/reverseproxy.go73-212 modules/caddyhttp/reverseproxy/reverseproxy.go450-486 modules/caddyhttp/reverseproxy/hosts.go69-225

关键集成点

  1. 上游可用性:在上游被选中之前,会调用其 Available() 方法,该方法会检查

    • 上游是否健康(来自主动和被动检查)
    • 上游是否达到最大容量(超过 max_requests
    • 断路器(如果已配置)是否打开
  2. 故障计数:

    • 对于被动健康检查,向上游的请求失败时会进行故障计数
    • 故障在配置的 fail_duration 后被遗忘
    • 每个上游都有主动健康检查的连续失败和通过计数
  3. 健康状态存储:

    • 主动健康状态按代理处理程序维护
    • 被动健康状态全局维护在一个共享使用池中
    • 这允许在配置重新加载时重用连接信息

来源: modules/caddyhttp/reverseproxy/hosts.go269-270 modules/caddyhttp/reverseproxy/reverseproxy.go583-640

主机健康管理

主机的健康状态通过原子操作进行管理,以确保线程安全

来源: modules/caddyhttp/reverseproxy/hosts.go34-225

每个 Upstream 引用一个 Host 对象,该对象跟踪

  1. 活动请求计数
  2. 被动健康检查的失败计数
  3. 主动健康检查的连续通过和失败次数

状态通过原子操作更新,以确保在并发环境中的线程安全。

示例和最佳实践

配置示例

以下是包含主动和被动健康检查的 Caddyfile 配置示例

example.com {
    reverse_proxy {
        to backend1.example.com:8080 backend2.example.com:8080

        # Active health checks
        health_uri /health
        health_interval 10s
        health_timeout 5s
        health_status 200
        health_body My\\sService\\sIs\\sHealthy
        health_passes 2
        health_fails 3
        
        # Passive health checks
        fail_duration 30s
        max_fails 5
        unhealthy_status 500 502 503 504
        unhealthy_latency 1s
    }
}

最佳实践

  1. 配置适当的超时:

    • health_timeout 设置为低于 health_interval 以避免检查重叠
    • 根据您预期瞬时错误持续的时间设置 fail_duration
  2. 使用适当的健康检查端点:

    • 在您的后端创建一个专用的 /health/status 端点
    • 该端点应验证关键依赖项,例如数据库
    • 保持端点轻量,以避免健康检查造成过大负载
  3. 设置有意义的阈值:

    • 对于关键服务,在标记为宕机之前,需要多次失败(fails > 1)
    • 对于主动检查,考虑在标记为可用之前,要求多次通过(passes > 1)
    • 对于被动检查,根据流量和错误容忍度设置 max_fails
  4. 平衡灵敏度和稳定性:

    • 更积极的健康检查(较低的阈值)可以更快地检测到故障,但可能导致抖动
    • 更保守的检查(较高的阈值)更稳定,但对问题的响应较慢
  5. 考虑使用断路器进行高级保护:

    • 断路器可以为过载后端提供更复杂的保护
    • 它们通常监控错误率、延迟模式和其他指标来做出决策

来源: modules/caddyhttp/reverseproxy/caddyfile.go335-633 modules/caddyhttp/reverseproxy/healthchecks.go38-69

实现细节

主动健康检查器工作流程

主动健康检查器在后台 goroutine 中运行,并执行以下操作

  1. 根据配置的间隔启动计时器
  2. 对于每个上游
    • 使用配置的参数创建 HTTP 请求
    • 以适当的超时向上游发送请求
    • 根据配置的条件评估响应
    • 根据结果更新健康状态

当后端被发现不健康时,会通过 Caddy 的事件系统发出一个可被监控的事件。

来源: modules/caddyhttp/reverseproxy/healthchecks.go272-294 modules/caddyhttp/reverseproxy/healthchecks.go298-375

被动健康检查器工作流程

被动健康检查器集成到反向代理请求流程中

  1. 向上游的每个请求之后
    • 检查状态码是否与配置的不健康状态码匹配
    • 检查响应延迟是否超过配置的阈值
  2. 如果满足失败条件
    • 增加上游的失败计数
    • 安排一个计时器,在 fail_duration 后递减失败计数
  3. 在选择上游之前
    • 检查失败计数是否超过 max_fails
    • 如果是,则认为上游不健康并避免选择它

来源: modules/caddyhttp/reverseproxy/reverseproxy.go583-640 modules/caddyhttp/reverseproxy/reverseproxy.go916-928

局限性

  1. 动态上游:主动健康检查不适用于动态上游,因为这些上游是为每个请求创建的。出于类似原因,被动健康检查对动态上游的有效性有限。

  2. 健康检查共享:主动健康检查状态是按处理程序划分的,而被动健康检查状态是全局的。这意味着在使用主动健康检查时,不同的处理程序可能对上游的健康状态有不同的看法。

  3. Unix 套接字后端:当使用 Unix 套接字上游时,健康检查会使用特殊处理来支持正确的健康检查。

来源: modules/caddyhttp/reverseproxy/healthchecks.go38-69 modules/caddyhttp/reverseproxy/healthchecks.go353-355

结论

Caddy 的健康检查系统提供了强大的机制来检测并避开不健康的后端。通过结合主动和被动健康检查,您可以创建一个可靠的反向代理设置,该设置可自动适应不断变化的后端条件。