news 2026/9/22 18:40:13

Apache APISIX 上游健康检查完全指南:主动检查、被动检查与状态观测

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Apache APISIX 上游健康检查完全指南:主动检查、被动检查与状态观测
  • API网关
  • 后端
  • 云原生
  • 微服务

【免费下载链接】apisix

The Cloud-Native API Gateway and AI Gateway

项目地址:https://gitcode.com/gh_mirrors/api/apisix
点击查看免费下载

Apache APISIX 内置的健康检查功能用于实时监控上游(upstream)节点的可用性,当节点发生故障或迁移时,自动将请求代理到健康节点,最大程度避免服务不可用。本文以官方教程 docs/zh/latest/tutorials/health-check.md 为骨架,结合仓库源码(apisix/healthcheck_manager.luaapisix/schema_def.luaapisix/control/v1.lua)深入讲解两种健康检查模式、全部配置属性、状态机与计数器机制,以及通过控制接口观测节点状态的具体方法,帮助你掌握一套可落地的上游高可用治理方案。

两种健康检查模式

APISIX 的健康检查基于 lua-resty-healthcheck 库实现,分为主动检查被动检查两种模式,二者可以在upstream.checks中组合使用。

主动健康检查

主动健康检查由 APISIX 根据预设的探针类型,主动向上游节点发起探测请求,以确认节点存活性。目前支持HTTPHTTPSTCP三种探针类型(对应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.luacreate_checker按需创建,而非随配置加载即创建。
  • 如果没有健康的节点,请求会继续发送给上游(即 APISIX 不会因此直接拒绝请求)。

:::

健康检查属性详解

健康检查配置位于upstream.checks之下,分为activepassive两个子对象。以下属性表格完整对应 apisix/schema_def.lua 中的校验定义,其中标注的默认值、有效范围均与源码中的 schema 声明一致。

主动检查属性(upstream.checks.active)

名称类型有效值默认值描述
typestringhttphttpstcphttp主动检查的探针类型
timeoutnumber1主动检查的超时时间(秒)
concurrencyinteger10同时检查的目标节点数
http_pathstring/主动检查的 HTTP 请求路径
hoststring${upstream.node.host}主动检查的 HTTP 请求主机名(Host 头)
portinteger165535${upstream.node.port}主动检查的 HTTP 请求端口
https_verify_certificatebooleantrueHTTPS 类型检查时,是否校验远程主机的 SSL 证书
req_headersarray[]HTTP/HTTPS 类型检查时附加的请求头,如["User-Agent: curl/7.29.0"]
http_methodstringGETPOSTPUTGET主动检查使用的 HTTP 方法(schema 中额外支持的字段)
http_req_bodystring""主动检查请求体(schema 中额外支持的字段)

说明:http_methodhttp_req_body在 schema_def.lua 中定义(方法枚举与路由方法一致),属于教程属性表之外、源码确认的可用字段。

健康节点判定(active.healthy)

名称类型有效值默认值描述
intervalinteger>= 11对健康节点的检查间隔(秒)
http_statusesarray200599[200, 302]HTTP/HTTPS 检查时视为健康的响应状态码
successesinteger12542连续成功多少次后判定节点健康

非健康节点判定(active.unhealthy)

名称类型有效值默认值描述
intervalinteger>= 11对非健康节点的检查间隔(秒)
http_statusesarray200599[429, 404, 500, 501, 502, 503, 504, 505]HTTP/HTTPS 检查时视为失败的状态码
http_failuresinteger12545HTTP/HTTPS 类型连续失败多少次判定节点非健康
tcp_failuresinteger12542TCP 类型连续失败多少次判定节点非健康
timeoutsinteger12543连续超时多少次判定节点非健康

被动检查属性(upstream.checks.passive)

名称类型有效值默认值描述
typestringhttphttpstcphttp被动检查的类型
healthy.http_statusesarray200599[200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308]视为健康的响应状态码
healthy.successesinteger02545连续成功多少次判定节点健康
unhealthy.http_statusesarray200599[429, 500, 503]视为失败的响应状态码
unhealthy.tcp_failuresinteger02542TCP 连续失败多少次判定节点非健康
unhealthy.timeoutsinteger02547连续超时多少次判定节点非健康
unhealthy.http_failuresinteger02545HTTP 连续失败多少次判定节点非健康

在 schema_def.lua 中,checks对象使用anyOf约束:至少必须配置active,也可以同时配置activepassive,即不允许仅配置 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" } ]

其中statuscounter是判断节点健康状况最核心的字段。

按资源类型定向查询

源码 control/v1.lua 显示,/v1/healthcheck/{src_type}/{src_id}支持按资源定位查询,src_type支持routesservicesupstreamsstream_routes;还可以追加checkers子资源,返回该资源拥有的全部检查器(upstream 检查器 + 各插件实例检查器)。例如:

curl http://127.0.0.1:9090/v1/healthcheck/upstreams/healthycheck -s | jq .

节点状态机与 counter 计数器

APISIX 中节点共有四种状态:healthyunhealthymostly_healthymostly_unhealthy

  • mostly_healthy:当前判定为健康,但健康检查期间并非所有探测都成功;
  • mostly_unhealthy:当前判定为不健康,但健康检查期间并非所有探测都失败。

节点的状态转换取决于本次健康检查的成功或失败,以及counter中记录的tcp_failurehttp_failuresuccesstimeout_failure四个计数(转换关系见上图状态转换图)。

counter 信息说明

若健康检查失败,counter中的success计数会被置零;若健康检查成功,则tcp_failurehttp_failuretimeout_failure会被置零。

名称描述作用
success健康检查成功的次数success大于healthy.successes配置值时,节点变为healthy状态
tcp_failureTCP 类型健康检查失败次数tcp_failure大于unhealthy.tcp_failures配置值时,节点变为unhealthy状态
http_failureHTTP 类型健康检查失败次数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.hostpass_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 完整定义了activepassive两套 schema(即前文属性表的校验来源),并通过anyOf = { {required = {"active"}}, {required = {"active", "passive"}} }强制要求active必须存在,从配置入口就杜绝了“只配置被动检查”的不可恢复陷阱。

总结

  • 主动检查是节点健康治理的“探针”,支持http/https/tcp三种类型,能提前感知并剔除故障节点;被动检查复用真实请求结果,零额外开销但存在滞后,二者需组合使用。
  • 所有阈值(successeshttp_failurestcp_failurestimeouts)与判定状态码(http_statuses)都可在upstream.checks中精细调优,schema 层(schema_def.lua)强制active必配。
  • 通过 Admin API 配置、通过控制接口/v1/healthcheck观测节点statuscounter,配合info级别日志即可完整掌握节点健康全貌;healthcheck_manager.lua 与 upstream.lua 则是理解其底层实现的最佳入口。
  • API网关
  • 后端
  • 云原生
  • 微服务

【免费下载链接】apisix

The Cloud-Native API Gateway and AI Gateway

项目地址:https://gitcode.com/gh_mirrors/api/apisix
点击查看免费下载

相关推荐

上一篇:Nextcloud AIO 部署上手:30 分钟搭好完整自托管网盘
下一篇:如何3步快速解密QQ音乐加密文件:qmcdump完整实战指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/22 18:36:10

WinSW 贡献指南:环境准备、源码构建与测试验证全流程

WinSW 贡献指南:环境准备、源码构建与测试验证全流程 【免费下载链接】winsw A wrapper executable that can run any executable as a Windows service, in a permissive license. 项目地址: https://gitcode.com/gh_mirrors/wi/winsw WinSW(Win…

作者头像 李华
网站建设 2026/9/22 12:42:31

RK3588上FFmpeg+MPP实现H.265转H.264硬件加速

1. 为什么在RK3588上做视频转码绕不开MPP先聊一个很多人踩过的坑:拿到RK3588开发板,装好Ubuntu,兴致勃勃跑了一条常见的FFmpeg命令想把H.265视频转成H.264,结果发现CPU占用直接拉满,4K视频转码速度惨不忍睹&#xff0c…

作者头像 李华
网站建设 2026/9/22 12:32:11

缓存命中账不平?Base URL 填 TaoToken 通道再核 Output Token

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/22 11:21:54

cgroup v2实战指南:runc如何精细管控容器CPU、内存与PID资源

cgroup v2实战指南:runc如何精细管控容器CPU、内存与PID资源 【免费下载链接】runc CLI tool for spawning and running containers according to the OCI specification 项目地址: https://gitcode.com/gh_mirrors/ru/runc runc 是依据 OCI 规范启动和运行容…

作者头像 李华