ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Apache APISIX 上游节点健康检查(Health Check)完整实战指南:主动/被动探测、状态机与 Control API 监控

Apache APISIX 上游节点健康检查(Health Check)完整实战指南:主动/被动探测、状态机与 Control API 监控 Apache APISIX 上游节点健康检查Health Check完整实战指南主动/被动探测、状态机与 Control API 监控【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix本篇指南系统讲解 Apache APISIX 上游Upstream健康检查机制它如何通过主动探测Active Check与被动观测Passive Check识别并隔离故障节点核心配置项的含义与默认值以及如何通过 Control API 实时查看节点健康状态与计数器。读完本文你将掌握在 Route/Service/Upstream 上配置健康检查、理解节点状态机迁移规则、并据此搭建自愈型网关的完整方法。本文以 docs/en/latest/tutorials/health-check.md 为主干并结合仓库内源码、Schema 定义与测试用例展开。概述为什么网关需要健康检查在微服务架构中上游节点可能随时发生故障、宕机或迁移。如果网关不做任何探活就会持续把用户请求转发到已经不可用的节点导致大量 5xx 错误与服务不可用。APISIX 的健康检查功能正是为了解决这一问题当上游节点异常时将请求代理到健康的节点最大程度避免服务不可用的问题。APISIX 的健康检查基于 lua-resty-healthcheck 中require(resty.healthcheck)的调用可以看出分为两种模式主动检查Active Check网关主动按预设的探针类型HTTP、HTTPS、TCP探测上游节点的存活状态被动检查Passive Check根据网关转发请求后得到的响应状态间接判断上游节点是否健康。从源码实现上看健康检查器是在请求转发阶段按需创建的。在 apisix/upstream.lua 中可以看到if nodes_count 1 then local checker fetch_healthchecker(up_conf) api_ctx.up_checker checker end这段代码揭示了三个重要行为也与文档中的提示一致只有当上游被请求命中时才会启动健康检查——配置了checks但从未被访问的 Upstream 不会产生任何探测流量节点数大于 1 时才创建 checker——当 Upstream 只有一个节点时无论其健康与否请求都会打到它因此无需探活当没有健康节点可选时网关仍会继续访问上游——健康检查用于尽量规避故障但不会在全灭时直接拒绝流量。主动检查Active Check网关主动探活主动检查的核心思路是APISIX 按照配置的间隔与探测类型主动向上游节点发起探测请求或 TCP 连接。探测支持三种类型HTTP、HTTPS、TCP。其判定逻辑如下对健康节点A连续发起N 次探测失败后节点被标记为unhealthy不健康此后负载均衡器会忽略该节点不再向其转发请求对不健康节点连续M 次探测成功后节点会被重新标记为healthy重新参与流量分发。也就是说主动检查能够实现故障自动摘除 恢复自动加回的闭环是保障上游可用性的主力手段。主动检查配置参数详解配置项配置类型值类型取值范围默认值说明upstream.checks.active.type主动检查stringhttphttpstcphttp主动检查的探测类型upstream.checks.active.timeout主动检查integer—1主动检查的超时时间单位秒upstream.checks.active.concurrency主动检查integer—10主动检查时同时探测的目标数量upstream.checks.active.http_path主动检查string—/主动检查发起的 HTTP 请求路径upstream.checks.active.host主动检查string—${upstream.node.host}主动检查 HTTP 请求的 Host 请求头upstream.checks.active.port主动检查integer1到65535${upstream.node.port}主动检查 HTTP 请求的目标端口upstream.checks.active.https_verify_certificate主动检查boolean—true使用 HTTPS 类型探测时是否校验远端主机的 SSL 证书upstream.checks.active.req_headers主动检查array—[]使用 HTTP/HTTPS 类型探测时附加的请求头信息upstream.checks.active.healthy.interval主动检查健康节点integer 11健康节点的检查间隔单位秒upstream.checks.active.healthy.http_statuses主动检查健康节点array200到599[200, 302]HTTP/HTTPS 类型探测中判定节点健康的状态码集合upstream.checks.active.healthy.successes主动检查健康节点integer1到2542判定节点健康所需连续成功的次数upstream.checks.active.unhealthy.interval主动检查不健康节点integer 11不健康节点的检查间隔单位秒upstream.checks.active.unhealthy.http_statuses主动检查不健康节点array200到599[429, 404, 500, 501, 502, 503, 504, 505]HTTP/HTTPS 类型探测中判定节点不健康的状态码集合upstream.checks.active.unhealthy.http_failures主动检查不健康节点integer1到2545HTTP/HTTPS 类型探测中判定节点不健康所需连续失败的次数upstream.checks.active.unhealthy.tcp_failures主动检查不健康节点integer1到2542TCP 类型探测中判定节点不健康所需连续失败的次数upstream.checks.active.unhealthy.timeouts主动检查不健康节点integer1到2543判定节点不健康所需连续超时的次数以上取值约束与默认值均可从仓库中的 Schema 定义得到印证参见 apisix/schema_def.lua 中的health_checker结构active.type的枚举为{http, https, tcp}、healthy.successes的取值范围为1~254默认2、unhealthy.http_statuses默认{429, 404, 500, 501, 502, 503, 504, 505}等与文档表格完全一致。同时该 Schema 的anyOf规定checks对象必须至少包含active即{required {active}}或{required {active, passive}}说明checks配置不能只写passive而省略active。理解主动检查的工作流从源码 apisix/upstream.lua 的create_checker可以看到完整链路通过healthcheck.new({...})创建检查器实例其name为upstream# .. value.key共享内存名为upstream-healthcheck将 Upstream 下每个节点通过checker:add_target(node.host, port or node.port, host, true, host_hdr)注册为探测目标其中host对应active.host配置未配置时使用节点自身 host端口优先取active.port否则取节点端口检查器创建后会注册一个清理句柄add_clean_handler在配置变更时通过release_checkerchecker:delayed_clear(3)checker:stop()释放旧检查器避免内存泄漏——t/node/healthcheck-leak-bugfix.t正是针对该场景的回归测试。主动检查的探测目标注册细节在create_checker中有一处值得注意的细节当 Upstream 设置了pass_host rewrite时探测请求的 Host 头会使用upstream.upstream_host当pass_host node时则使用节点的domain。这意味着主动检查的请求头行为与真实转发请求保持了一致性避免因 Host 头不一致导致探测结果失真。被动检查Passive Check基于真实流量的观测被动检查不额外发起探测而是通过分析 APISIX 转发给上游的请求的响应状态来判断节点是否健康对健康节点A连续N 次请求失败后节点被标记为unhealthy。相比主动检查被动检查不会产生额外的探测流量、更省资源但由于它是事后发现问题的无法提前感知节点状态期间会存在一定数量的失败请求。:::note 重要提示由于不健康节点无法接收请求已被负载均衡器摘除单独使用被动检查策略无法让节点重新变回健康没有请求就没有新的观测样本因此通常必须结合主动检查策略一起使用。:::被动检查配置参数详解配置项配置类型值类型取值范围默认值说明upstream.checks.passive.type被动检查stringhttphttpstcphttp被动检查的类型upstream.checks.passive.healthy.http_statuses被动检查健康节点array200到599[200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308]HTTP/HTTPS 类型下判定节点健康的状态码集合upstream.checks.passive.healthy.successes被动检查健康节点integer0到2545判定节点健康所需连续成功的次数upstream.checks.passive.unhealthy.http_statuses被动检查不健康节点array200到599[429, 500, 503]HTTP/HTTPS 类型下判定节点不健康的状态码集合upstream.checks.passive.unhealthy.tcp_failures被动检查不健康节点integer0到2542TCP 类型下判定节点不健康所需连续失败的次数upstream.checks.passive.unhealthy.timeouts被动检查不健康节点integer0到2547判定节点不健康所需连续超时的次数upstream.checks.passive.unhealthy.http_failures被动检查不健康节点integer0到2545HTTP/HTTPS 类型下判定节点不健康所需连续失败的次数注意被动检查的successes、tcp_failures、timeouts、http_failures取值范围为0~254允许配置为0这与主动检查1~254不同设计上更灵活。仓库测试t/node/healthcheck-passive.t与t/node/healthcheck-passive-resty-events.t覆盖了被动检查含与retries组合、基于事件机制的行为验证。完整配置示例通过 Admin API 启用健康检查可以通过 Admin API 在 Route 中启用健康检查。以下示例来自原文档展示了主动 被动检查的完整组合配置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 } } } } }使用前的准备获取 admin_key示例中的$admin_key来自config.yaml。可执行以下命令从 conf/config.yaml 中取出并保存为环境变量admin_key$(yq .deployment.admin.admin_key[0].key conf/config.yaml | sed s///g)示例配置要点解读主动检查每 2 秒对健康节点探测一次healthy.interval: 2只要 1 次成功即视为健康successes: 1对不健康节点每 1 秒探测一次unhealthy.interval: 1连续 2 次 HTTP 失败即判定不健康http_failures: 2探测路径为/statusHost 头为foo.com并附加User-Agent: curl/7.29.0请求头被动检查健康状态码集合收紧为[200, 201]连续 3 次成功即视为健康只要响应状态码为500即记为失败连续 3 次 HTTP 失败或 3 次 TCP 失败判定不健康。观察故障节点的日志当 APISIX 检测到不健康节点时error log 中会输出如下信息需将错误日志级别调整为info才能看到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从日志可以看到(1/2)表示 TCP 失败计数为 1、阈值unhealthy.tcp_failures为 2当计数达到(2/2)后节点127.0.0.1:1980即被标记为不健康。这正是文档表格中连续失败次数达到阈值即摘除节点规则在真实运行时的直观体现。测试用例 t/node/healthcheck.t 中同样以http_failures: 2等参数验证了该摘除与恢复流程。通过 Control API 查看健康检查状态健康检查状态可以通过 Control API 的GET /v1/healthcheck获取。Control API 默认监听在127.0.0.1:9090详见 docs/en/latest/control-api.mdcurl http://127.0.0.1:9090/v1/healthcheck/upstreams/healthycheck -s | jq .若 Control API 被浏览器访问且请求头Accept: text/html会返回一个 HTML 表格页面APISIX upstream check status用绿色/红色背景直观标识健康与不健康节点——该渲染逻辑可以在 apisix/control/v1.lua 的HTML_TEMPLATE中看到。响应结构与字段说明[ { 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 } ]每个返回对象的字段含义name健康检查器对应的资源 ID如/apisix/routes/1type健康检查类型取值为[http, https, tcp]nodes健康检查器的目标节点列表nodes[i].ip节点 IP 地址nodes[i].port节点端口nodes[i].status健康检查结果取值为[healthy, unhealthy, mostly_healthy, mostly_unhealthy]nodes[i].counter.success健康检查成功次数nodes[i].counter.http_failureHTTP 失败次数nodes[i].counter.tcp_failureTCP 连接/读/写失败次数nodes[i].counter.timeout_failure超时次数。按资源类型精确查询除全量查询外还可以使用GET /v1/healthcheck/$src_type/$src_id查询特定资源的节点健康状态其中$src_type支持routes、services、upstreams例如curl http://127.0.0.1:9090/v1/healthcheck/upstreams/1从 apisix/control/v1.lua 的_M.get_health_checker实现可以看到该接口会解析 URI 段、按src_type在 routes/services/upstreams 中定位资源并通过iter_and_find_healthcheck_info找到对应检查器若资源不存在返回 404src_type非法返回 400资源未配置checks则提示 no checker for ...。:::note 展示条件只有当 Upstream配置了健康检查器且在某个 worker 进程中服务过请求时其状态才会出现在结果列表中。这再次印证了健康检查按需启动的设计。:::节点状态机与 Counter 计数机制四种节点状态APISIX 中节点存在四种状态healthy、unhealthy、mostly_unhealthy、mostly_healthymostly_healthy当前节点被视为健康但在健康检查过程中节点的健康状态并非持续成功即健康判定过程中出现过失败但尚未跌破阈值mostly_unhealthy当前节点被视为不健康但在健康检查过程中节点的健康检测并非持续失败即已判定不健康但后续探测出现过成功尚未完全恢复。节点状态的迁移取决于当前健康检查的成功/失败以及counter中四项关键指标的记录tcp_failure、http_failure、success、timeout_failure。状态迁移图状态迁移规则要点所有节点初始即为healthy状态无需任何初始探测Counter 只在状态发生变化时重置与更新因此当节点处于healthy且后续检查全部成功时success计数不会被更新始终保持为 0。Counter 四项指标名称描述用途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状态Counter 的联动重置规则健康检查失败时success计数会重置为 0健康检查成功时tcp_failure、http_failure、timeout_failure会重置为 0。这一成功/失败互斥清零的设计保证了只有连续的成功或失败才能触发状态迁移与文档中连续 N 次的判定语义完全一致。实战建议与注意事项主动检查优先被动检查辅助主动检查能实现故障摘除与自动恢复的完整闭环被动检查省流量但无法恢复节点且会先产生一部分失败请求。生产环境推荐两者结合主动检查负责探活与恢复被动检查负责快速感知真实请求的失败。合理设置阈值避免抖动unhealthy.http_failures/tcp_failures/timeouts过小容易因瞬时抖动误摘节点healthy.successes过小则可能在节点刚恢复时过早放量。可从文档默认值如http_failures: 5、successes: 2出发结合业务容忍度调整。健康检查按需启动只有被请求命中的、且节点数大于 1 的 Upstream 才会创建检查器查询状态时若看不到某 Upstream可先确认其是否已被访问。探测细节对齐真实流量active.host、req_headers、https_verify_certificate等参数会影响探测结果配置时应尽量模拟真实请求Host、User-Agent、证书校验避免探测通过但真实请求失败的误判。监控可视化利用GET /v1/healthcheck与GET /v1/healthcheck/$src_type/$src_id接口将节点状态与counter指标接入监控大盘可对上游集群的健康状况做持续观测与告警。延伸阅读Control API 文档/v1/healthcheck接口的完整说明与响应字段定义Upstream Schema 定义checks配置项的字段约束、枚举与默认值health_checker结构检查器创建源码create_checker/fetch_healthchecker的实现细节与节点注册逻辑健康检查状态接口实现get_health_checkers/get_health_checker的查询与 HTML 渲染逻辑健康检查测试用例覆盖健康节点摘除、恢复、被动检查等行为的端到端测试同目录下还有healthcheck2.t、healthcheck3.t、healthcheck-passive.t、healthcheck-https.t、healthcheck-ipv6.t等专项用例。【免费下载链接】apisixThe Cloud-Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/ap/apisix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表