- API网关
- 后端
- 云原生
- 微服务
【免费下载链接】apisix
The Cloud-Native API Gateway and AI Gateway
Apache APISIX 内置的健康检查功能用于实时监控上游(upstream)节点的可用性,当节点发生故障或迁移时,自动将请求代理到健康节点,最大程度避免服务不可用。本文以官方教程 docs/zh/latest/tutorials/health-check.md 为骨架,结合仓库源码(apisix/healthcheck_manager.lua、apisix/schema_def.lua、apisix/control/v1.lua)深入讲解两种健康检查模式、全部配置属性、状态机与计数器机制,以及通过控制接口观测节点状态的具体方法,帮助你掌握一套可落地的上游高可用治理方案。
两种健康检查模式
APISIX 的健康检查基于 lua-resty-healthcheck 库实现,分为主动检查与被动检查两种模式,二者可以在upstream.checks中组合使用。
主动健康检查
主动健康检查由 APISIX 根据预设的探针类型,主动向上游节点发起探测请求,以确认节点存活性。目前支持HTTP、HTTPS、TCP三种探针类型(对应upstream.checks.active.type的取值,见 schema_def.lua)。
其状态切换逻辑为:
- 当发向健康节点 A 的N 个连续探针均失败时(N 由
unhealthy配置决定),节点被标记为不健康,随后会被负载均衡器忽略,不再接收请求; - 若某个不健康节点连续M 个探针均成功(M 由
healthy配置决定),节点被重新标记为健康,恢复代理。
主动检查能提前发现节点故障,是保证高可用的主要手段,代价是会产生额外的探测流量。
被动健康检查
被动健康检查不主动发起探测,而是通过分析APISIX 转发到上游节点的真实请求响应状态来判断节点是否健康。它的优点是零额外探针开销,但缺点是无法提前感知节点状态——节点真正出问题的那几笔请求已经失败,因此会存在一定量的失败请求。
同样的逻辑,若发向健康节点 A 的 N 个连续请求均被判定失败,该节点会被标记为不健康。
:::note 注意
由于不健康的节点无法再收到请求,仅配置被动健康检查时,节点一旦变不健康将永远无法被重新标记为健康。因此实践中必须将被动检查与主动检查组合使用,由主动检查负责“恢复”节点。
:::
:::tip 提示
- 只有在
upstream被请求时才会启动健康检查;若upstream已配置但从未被请求,健康检查不会触发启动。对应源码中健康检查器(checker)由apisix/healthcheck_manager.lua的create_checker按需创建,而非随配置加载即创建。 - 如果没有健康的节点,请求会继续发送给上游(即 APISIX 不会因此直接拒绝请求)。
:::
健康检查属性详解
健康检查配置位于upstream.checks之下,分为active与passive两个子对象。以下属性表格完整对应 apisix/schema_def.lua 中的校验定义,其中标注的默认值、有效范围均与源码中的 schema 声明一致。
主动检查属性(upstream.checks.active)
| 名称 | 类型 | 有效值 | 默认值 | 描述 |
|---|---|---|---|---|
type | string | httphttpstcp | http | 主动检查的探针类型 |
timeout | number | — | 1 | 主动检查的超时时间(秒) |
concurrency | integer | — | 10 | 同时检查的目标节点数 |
http_path | string | — | / | 主动检查的 HTTP 请求路径 |
host | string | — | ${upstream.node.host} | 主动检查的 HTTP 请求主机名(Host 头) |
port | integer | 1至65535 | ${upstream.node.port} | 主动检查的 HTTP 请求端口 |
https_verify_certificate | boolean | — | true | HTTPS 类型检查时,是否校验远程主机的 SSL 证书 |
req_headers | array | — | [] | HTTP/HTTPS 类型检查时附加的请求头,如["User-Agent: curl/7.29.0"] |
http_method | string | GETPOSTPUT等 | GET | 主动检查使用的 HTTP 方法(schema 中额外支持的字段) |
http_req_body | string | — | "" | 主动检查请求体(schema 中额外支持的字段) |
说明:
http_method、http_req_body在 schema_def.lua 中定义(方法枚举与路由方法一致),属于教程属性表之外、源码确认的可用字段。
健康节点判定(active.healthy)
| 名称 | 类型 | 有效值 | 默认值 | 描述 |
|---|---|---|---|---|
interval | integer | >= 1 | 1 | 对健康节点的检查间隔(秒) |
http_statuses | array | 200至599 | [200, 302] | HTTP/HTTPS 检查时视为健康的响应状态码 |
successes | integer | 1至254 | 2 | 连续成功多少次后判定节点健康 |
非健康节点判定(active.unhealthy)
| 名称 | 类型 | 有效值 | 默认值 | 描述 |
|---|---|---|---|---|
interval | integer | >= 1 | 1 | 对非健康节点的检查间隔(秒) |
http_statuses | array | 200至599 | [429, 404, 500, 501, 502, 503, 504, 505] | HTTP/HTTPS 检查时视为失败的状态码 |
http_failures | integer | 1至254 | 5 | HTTP/HTTPS 类型连续失败多少次判定节点非健康 |
tcp_failures | integer | 1至254 | 2 | TCP 类型连续失败多少次判定节点非健康 |
timeouts | integer | 1至254 | 3 | 连续超时多少次判定节点非健康 |
被动检查属性(upstream.checks.passive)
| 名称 | 类型 | 有效值 | 默认值 | 描述 |
|---|---|---|---|---|
type | string | httphttpstcp | http | 被动检查的类型 |
healthy.http_statuses | array | 200至599 | [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308] | 视为健康的响应状态码 |
healthy.successes | integer | 0至254 | 5 | 连续成功多少次判定节点健康 |
unhealthy.http_statuses | array | 200至599 | [429, 500, 503] | 视为失败的响应状态码 |
unhealthy.tcp_failures | integer | 0至254 | 2 | TCP 连续失败多少次判定节点非健康 |
unhealthy.timeouts | integer | 0至254 | 7 | 连续超时多少次判定节点非健康 |
unhealthy.http_failures | integer | 0至254 | 5 | HTTP 连续失败多少次判定节点非健康 |
在 schema_def.lua 中,checks对象使用anyOf约束:至少必须配置active,也可以同时配置active与passive,即不允许仅配置 passive 而不配置 active——这与上文“仅被动检查无法恢复节点”的结论在 schema 层互相印证。
通过 Admin API 启用健康检查
可以通过 Admin API 在路由(Route)中为 upstream 配置健康检查。先获取admin_key:
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')然后创建路由并启用健康检查:
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' { "uri": "/index.html", "plugins": { "limit-count": { "count": 2, "time_window": 60, "rejected_code": 503, "key": "remote_addr" } }, "upstream": { "nodes": { "127.0.0.1:1980": 1, "127.0.0.1:1970": 1 }, "type": "roundrobin", "retries": 2, "checks": { "active": { "timeout": 5, "http_path": "/status", "host": "foo.com", "healthy": { "interval": 2, "successes": 1 }, "unhealthy": { "interval": 1, "http_failures": 2 }, "req_headers": ["User-Agent: curl/7.29.0"] }, "passive": { "healthy": { "http_statuses": [200, 201], "successes": 3 }, "unhealthy": { "http_statuses": [500], "http_failures": 3, "tcp_failures": 3 } } } } }'该示例同时配置了主动与被动检查:主动检查以 5 秒超时、路径/status、Host 为foo.com探测两个节点,健康阈值 1 次成功、非健康阈值 2 次 HTTP 失败;被动检查则依据真实请求响应判定。
观测探针结果日志
启用成功后,若 APISIX 探测到不健康节点,会在错误日志中输出类似如下内容:
enabled healthcheck passive while logging request failed to receive status line from 'nil (127.0.0.1:1980)': closed unhealthy TCP increment (1/2) for '(127.0.0.1:1980)' failed to receive status line from 'nil (127.0.0.1:1980)': closed unhealthy TCP increment (2/2) for '(127.0.0.1:1980':::tip 提示
需要将错误日志级别调整为info才能观测到上述日志(对应 conf/config.yaml 中的 error_log 级别配置)。
:::
通过控制接口获取健康检查信息
APISIX 的控制接口(Control API,默认监听127.0.0.1:9090)提供了健康检查信息的查询入口,该接口实现在 apisix/control/v1.lua 中。
查询全部健康检查信息
curl -i http://127.0.0.1:9090/v1/healthcheck响应示例:
[ { "nodes": {}, "name": "/apisix/routes/1", "type": "http" }, { "nodes": [ { "port": 1970, "hostname": "127.0.0.1", "status": "healthy", "ip": "127.0.0.1", "counter": { "tcp_failure": 0, "http_failure": 0, "success": 0, "timeout_failure": 0 } }, { "port": 1980, "hostname": "127.0.0.1", "status": "healthy", "ip": "127.0.0.1", "counter": { "tcp_failure": 0, "http_failure": 0, "success": 0, "timeout_failure": 0 } } ], "name": "/apisix/routes/example-hc-route", "type": "http" } ]其中status与counter是判断节点健康状况最核心的字段。
按资源类型定向查询
源码 control/v1.lua 显示,/v1/healthcheck/{src_type}/{src_id}支持按资源定位查询,src_type支持routes、services、upstreams、stream_routes;还可以追加checkers子资源,返回该资源拥有的全部检查器(upstream 检查器 + 各插件实例检查器)。例如:
curl http://127.0.0.1:9090/v1/healthcheck/upstreams/healthycheck -s | jq .节点状态机与 counter 计数器
APISIX 中节点共有四种状态:healthy、unhealthy、mostly_healthy、mostly_unhealthy。
mostly_healthy:当前判定为健康,但健康检查期间并非所有探测都成功;mostly_unhealthy:当前判定为不健康,但健康检查期间并非所有探测都失败。
节点的状态转换取决于本次健康检查的成功或失败,以及counter中记录的tcp_failure、http_failure、success、timeout_failure四个计数(转换关系见上图状态转换图)。
counter 信息说明
若健康检查失败,counter中的success计数会被置零;若健康检查成功,则tcp_failure、http_failure、timeout_failure会被置零。
| 名称 | 描述 | 作用 |
|---|---|---|
success | 健康检查成功的次数 | 当success大于healthy.successes配置值时,节点变为healthy状态 |
tcp_failure | TCP 类型健康检查失败次数 | 当tcp_failure大于unhealthy.tcp_failures配置值时,节点变为unhealthy状态 |
http_failure | HTTP 类型健康检查失败次数 | 当http_failure大于unhealthy.http_failures配置值时,节点变为unhealthy状态 |
timeout_failure | 节点健康检查超时次数 | 当timeout_failure大于unhealthy.timeouts配置值时,节点变为unhealthy状态 |
请注意:所有节点在没有初始探测的情况下以healthy状态启动,且计数器仅在状态更改时重置和更新。因此当节点处于healthy状态且后续检查全部成功时,success计数器不会更新,保持为零——这正是上述响应示例中两个健康节点的success均为0的原因。
源码视角:健康检查的底层机制
检查器(checker)的创建与复用
apisix/healthcheck_manager.lua 是整个健康检查能力的核心管理模块:
create_checker(L86-L152)负责基于up_conf.checks创建resty.healthcheck检查器,并将 upstream 的每个节点通过add_target注册为探测目标。值得注意的是,它会先检查 conf/config.yaml 中的全局开关disable_upstream_healthcheck——该开关默认false,置为true时会全局禁用所有上游健康检查(见 config.yaml.example);- 检查器目标与节点一一对应:每个目标以
ip:port:hostname:hostheader为唯一键,active.host或pass_host的变化会被识别为不同目标,从而正确更新共享内存(shm)中的探测记录; sync_checker_targets(L161-L223)在节点列表变化而checks配置不变时,对已有检查器做增量增删目标,保留已累计的健康状态,避免重建检查器导致状态丢失。
检查器如何影响请求分发
在 apisix/upstream.lua 中,每次请求处理时都会通过healthcheck_manager.fetch_checker获取当前 upstream 对应的检查器并存入api_ctx.up_checker,后续负载均衡在挑选节点时会查询检查器过滤掉不健康节点(fetch_node_status返回 false 即视为不可用,见 healthcheck_manager.lua)。从源码结构看,健康检查与负载均衡是同一请求路径上的协作关系:健康检查维护节点可用性视图,负载均衡基于该视图挑选节点。
配置校验层面
apisix/schema_def.lua 完整定义了active与passive两套 schema(即前文属性表的校验来源),并通过anyOf = { {required = {"active"}}, {required = {"active", "passive"}} }强制要求active必须存在,从配置入口就杜绝了“只配置被动检查”的不可恢复陷阱。
总结
- 主动检查是节点健康治理的“探针”,支持
http/https/tcp三种类型,能提前感知并剔除故障节点;被动检查复用真实请求结果,零额外开销但存在滞后,二者需组合使用。 - 所有阈值(
successes、http_failures、tcp_failures、timeouts)与判定状态码(http_statuses)都可在upstream.checks中精细调优,schema 层(schema_def.lua)强制active必配。 - 通过 Admin API 配置、通过控制接口
/v1/healthcheck观测节点status与counter,配合info级别日志即可完整掌握节点健康全貌;healthcheck_manager.lua 与 upstream.lua 则是理解其底层实现的最佳入口。
- API网关
- 后端
- 云原生
- 微服务
【免费下载链接】apisix
The Cloud-Native API Gateway and AI Gateway
相关推荐
Apache APISIX 健康检查(Health Check)完整实战指南:主动检查、被动检查与节点状态监控
Apache APISIX 健康检查(Health Check)完整实战指南:主动检查、被动检查与节点状态监控 导读 本文围绕 Apache APISIX(Cl
API网关后端云原生微服务Apache APISIX 健康检查(Health Check)完全指南:主动探测、被动感知与节点状态机
Apache APISIX 健康检查(Health Check)完全指南:主动探测、被动感知与节点状态机 导读 本指南以 Apache APISIX 官方教程文
后端微服务云原生Apache APISIX 上游节点健康检查(Health Check)完整实战指南:主动/被动探测、状态机与 Control API 监控
Apache APISIX 上游节点健康检查(Health Check)完整实战指南:主动/被动探测、状态机与 Control API 监控 本篇指南系统讲解
后端微服务云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考