跳到主要内容
版本:Dev

健康检查

AISIX 为进程、流量、配置和模型状态分别提供健康与状态端点。这些端点同时适用于 AISIX OSS,以及连接 AISIX Enterprise 或 AISIX Cloud 的网关。请使用与所监控条件对应的端点。要验证从调用方到模型服务提供方的完整路径,请通过网关发送测试请求。

问题端点监听器
这个实例是否应该被重启?GET /livez代理
此实例是否应接收代理流量?GET /readyz代理
此实例是否已应用任何有效配置?GET /status/ready指标/状态
此实例当前使用什么配置提供服务?GET /status/config指标/状态
模型是否可用于路由?GET /status/models指标/状态

这些端点不需要身份认证。启用 Prometheus 指标时会提供指标/状态端点;默认情况下已启用。请确保该监听器仅对监控和运维系统开放。

代理存活检查​

使用 /livez 检查进程存活状态:

curl -i "http://127.0.0.1:3000/livez"

健康进程返回 200 OK,响应体为 ok。

正在排空的实例同样返回 200。存活检查决定的是要不要重启实例,而排空是有意为之的工作:一个已被告知关闭的实例正在处理完它已经接收的请求,重启它恰好会杀掉这些请求。报告排空状态的是 /readyz,这样流量会被撤走,而实例不会在自己仍有进行中请求时被替换掉。

手动排查时可以追加 ?verbose=1。自动化探针不要依赖 verbose 响应体。

存活检查刻意保持较窄范围。它不能证明模型可用,也不能证明模型服务提供方请求能够成功。

它确实意味着网关已经加载了配置,但这只是承载该端点的监听器何时存在所带来的副作用。从 etcd 或控制面读取资源的网关,在应用第一个配置之前不会绑定代理监听器,因此在那之前 /livez 不是返回 503,而是根本不会有响应。参见启动与第一个配置。

流量就绪​

使用 /readyz 判断实例是否应接收流量:

curl -i "http://127.0.0.1:3000/readyz"

实例正在排空时,该端点返回 503 Service Unavailable。有效配置可用后,只要网关仍能使用该配置提供服务,实例就会保持就绪。

在应用第一个配置之前,/readyz 的表现取决于资源来源;对于使用 etcd 或控制面的网关,得到的并不是 503:承载该端点的代理监听器尚未绑定,探针只会得到被拒绝的连接。要观察这一阶段,请使用指标/状态监听器上的 GET /status/ready,参见启动与第一个配置。

控制面或配置存储中断不会仅仅因为最近没有更新就让运行中的网关变为未就绪。来源停滞通常会影响所有实例,将它们全部移出流量会中断流量路径,而不是把流量转移到健康实例。请单独监控配置新鲜度。

排查实例未就绪的原因时可以追加 ?verbose=1。自动化探针不要依赖 verbose 响应体。

在 Kubernetes 中,请将存活和就绪探针分别指向代理监听器上的 /livez 和 /readyz,并在同一个监听器上再配置一个 startupProbe,使网关仍在连接配置来源期间另外两个探针都不会动作。该探针需要多大的预算,参见启动与第一个配置。请为网关留出足够的终止时间,以排空进行中的请求和流式请求。

启动与第一个配置​

从 etcd 或控制面读取资源的网关,在应用第一个配置之前不会绑定代理监听器。这样可以避免流量到达没有任何资源可提供服务的实例。完成任意一次初始 etcd 连接后,各监听器的表现如下:

监听器可观察状态
代理未绑定。/livez、/readyz 以及所有面向调用方的端点都会拒绝连接。
指标/状态启用 Prometheus 指标时绑定。GET /status/ready 返回 503 Service Unavailable,响应体为 no configuration available;GET /status/config 报告状态 never_loaded。
Admin开源网关启用该监听器时,在等待期间绑定。它自己的 /livez 返回 200,/readyz 始终返回 503。

带凭据的初始 etcd 连接发生在 AISIX 创建任何监听器之前。如果该连接停滞,上述所有端点都不可用。该窗口是有上限的:启动时会先后连接两个提供方,因此最长为 etcd.dial_timeout_ms × 端点数 × 2。AISIX 仅在同时设置 etcd.user 和 etcd.password_env 时发送凭据;缺少其中任一项时,初始连接不产生任何 I/O。

无法连接 ratelimit.redis 或 cache.redis 时,AISIX 执行有界启动连接尝试的期间可能延迟所有监听器,但不会让监听器无限期保持关闭。尝试结束后,Redis 不再阻止监听器启动,受影响的子系统进入降级模式,AISIX 会在后台继续尝试接入 Redis。每个监听器仍须满足自身的启用和配置条件。

使用资源文件的网关会在加载文件后立即绑定监听器。从可用的磁盘快照恢复的使用 etcd 或连接控制面的网关也会立即绑定。

因此,指标/状态监听器是冷启动的主要信号。如果该监听器不可用,请参见网关正在运行,但代理端口拒绝连接,查看症状、日志和修复方法。etcd 超时的准确作用范围和默认值记录在 etcd 配置存储中。

设置 Kubernetes 启动探针的预算​

代理监听器上的 startupProbe 会在第一个配置可用前阻止存活和就绪检查动作。它的预算 periodSeconds x failureThreshold 必须覆盖 Redis 启动连接尝试、连接配置来源以及应用其中资源的时间。单节点 Redis 连接最多可能消耗一个 timeout_secs;集群和 Sentinel 模式最多可能消耗 timeout_secs ×(已配置端点数 + 1)。应把每个已配置的限流和缓存连接都计算在内。api7/aisix Helm Chart 使用 300 秒预算,即 periodSeconds: 2 和 failureThreshold: 150。

该预算为大规模配置留出余量,不是对启动时间的实测上限。

网关会在大约 0、1、3、7、15、31 和 63 秒时重试失败的读取,之后每分钟重试一次。请避免让探针预算恰好在下一次重试前结束。如果来源持续不可用并超过预算,Kubernetes 会重启容器,并可能报告 CrashLoopBackOff。替换后的进程会重复同样的等待,并在来源恢复后绑定代理监听器。请修复来源,而不是把探针改指向其它监听器。

关闭与排空​

AISIX 会把变为未就绪与关闭监听器分开处理,让负载均衡器有时间撤下该实例。收到 SIGTERM 或 SIGINT 时,网关会:

  1. 立即让 /readyz 返回 503 Service Unavailable,使下一次健康检查将其移出流量。/livez 保持 200:进程是健康的,排空期间不应被重启。
  2. 继续接受新连接,至少持续 shutdown.min_drain_secs,默认为 30 秒。
  3. 为 HTTP/1.1 响应添加 Connection: close,并向 HTTP/2 客户端发送 GOAWAY 帧,使客户端停止复用连接,而不会中断进行中的工作。WebSocket 升级(例如 Realtime 握手)仍会正常完成。
  4. 最小窗口结束后,不设自身期限地等待进行中请求数降为零,然后停止接受新连接。流式响应在结束前都计为进行中;打开的 Realtime WebSocket 会话(/v1/realtime)同样如此,从握手开始,直到会话关闭并记录完用量为止。
  5. 等待已接受的连接全部结束。在这些连接上到达的请求会被正常处理,并以 Connection: close 响应;在这些连接上新打开的 Realtime 会话会让网关一直保持运行,直到该会话关闭。空闲的连接池连接会被关闭。尚未发送请求的连接会一直保留,直到它发送请求、downstream.idle_timeout_secs 到期或客户端关闭连接。
  6. 在保留快照缓存的使用 etcd 或连接控制面的网关上,再最多等待 5 秒,让仍在途中的快照缓存写入落盘,然后退出。

请把 min_drain_secs 设置为大于 /readyz 状态变化后负载均衡器停止路由所需的时间。对于 Kubernetes,该时间为 periodSeconds x failureThreshold;对于外部负载均衡器,请使用检查间隔乘以重试次数。

config.yaml
shutdown:
min_drain_secs: 30

这个窗口是最小值,而不是关闭期限。窗口结束后,网关仍会等待进行中的请求数降为零。设为 0 会取消最小窗口,仅当没有任何系统通过健康检查将流量路由到该实例时才适用。

由于等待进行中工作数降为零的过程没有上限,整个流程的实际上限由部署平台决定——Kubernetes 中是 terminationGracePeriodSeconds,systemd 下是 TimeoutStopSec。请把它设置为大于 shutdown.min_drain_secs、最长请求、流式传输或 Realtime 会话时长,以及启用持久化时的 5 秒快照缓存排空这三者之和,并留出运维余量。还应加上任何 preStop 钩子的持续时间,因为它会消耗同一个 Kubernetes 终止预算。

宽限期结束时仍然打开的 Realtime 会话会随进程一起被关闭,与流式响应相同。

在默认的 downstream.idle_timeout_secs: 0 下,一条已打开却从不发送请求的连接(例如负载均衡器预先建立的连接)会让正在排空的网关一直保持运行,直到客户端关闭连接或平台终止进程。设置 downstream.idle_timeout_secs 可以为这段等待设定上限。在 TLS 监听器上,它在 TLS 握手完成后才生效;始终没有完成握手的连接不受它约束。

快照缓存的等待从在途请求结束后才开始,因此这部分是额外时间。5 秒上限固定;到期后网关记录告警并退出。原子文件替换可避免部分写入的快照,但下次进程可能恢复较旧快照,也可能没有可恢复快照。

备注

请把外部负载均衡器的健康检查指向 /readyz,而不是单纯的 TCP 连接探测。TCP 探测无法观察到就绪状态,它唯一能得到的信号就是监听器关闭——而这正是排空窗口要避免的那个事件。

在日志中观察排空过程​

使用排空日志中的字段,区分尚未完成的请求与仍保持打开或继续到达的连接:

日志内容字段写出时机
draining — /readyz now reports 503, still accepting new connectionsmin_drain_secs、in_flight、open_connections收到信号时写出一次。
still draining in-flight requestsin_flight、open_connections排空期间周期性写出。
request arrived while drainingmethod、path,以及该请求自身的 request_id、peer 和 downstream_request_id信号之后每到达一个请求写一条。
accepted a new downstream connection while drainingpeer、open_connections信号之后每接受一条连接写一条。

in_flight 统计正在处理的请求,包括流式响应和打开的 Realtime 会话。open_connections 还包括空闲连接池连接和健康探针连接。如果 in_flight 仍大于零,AISIX 仍在完成已接收的工作。如果 open_connections 增长,说明仍有其他组件在向正在排空的实例建立连接。

排查滚动更新期间失败的请求时,请按 peer 匹配 request arrived while draining 和 accepted a new downstream connection while draining。匹配到接受记录意味着连接在排空开始后到达;没有匹配记录则意味着客户端复用了较早的连接池连接。健康检查可能产生接受记录,但不会出现在请求到达记录中。

peer 和 downstream_request_id 提供访问日志与请求关联中描述的请求到达上下文。将 peer 与前置代理的连接记录匹配,并将 downstream_request_id 与其请求记录匹配。

配置状态​

指标/状态监听器提供两个配置检查。

GET /status/ready 是仅检查配置的启动门禁:

  • 应用第一个有效配置之前返回 503 Service Unavailable;
  • 有效配置可用后返回 200 OK;后续更新失败而 AISIX 使用最后已知的有效快照时也会返回 200 OK。

对于使用 etcd 或控制面的网关,应用第一个配置之前应当观察的就是这个端点,因为在那之前代理监听器尚未绑定。参见启动与第一个配置。

GET /status/config 用于说明 AISIX 观察到和应用的内容:

curl -sS "http://127.0.0.1:9090/status/config"

当资源更新没有反映到代理行为中时,请使用该端点。比较来源状态与已应用状态,然后检查被拒绝的资源和最近一次加载失败。有关完整响应字段、状态含义、Prometheus 指标和告警示例,请参阅配置状态。

配置状态不能替代调用方路径验证。预期快照应用后,请查询 GET /v1/models,并发送行为发生变更的请求。请参阅配置传播。

按模型检查运行时健康状态​

当网关已就绪,但路由避开某个模型或报告没有符合条件的目标时,请使用 GET /status/models:

curl -sS "http://127.0.0.1:9090/status/models"

每个已配置模型会报告以下高层状态之一:

  • healthy:可用于路由;
  • cooldown:在最近的上游失败后暂时移出路由;只有开启了冷却的模型才会进入该状态;
  • unhealthy:后台模型检查失败后被排除;
  • not_applicable:可用性由其目标决定的虚拟模型。

状态视图有助于识别冷却和后台检查失败,但不会验证调用方访问权限或模型服务提供方凭证。即使模型报告为健康,调用方 API Key、模型服务提供方密钥或上游响应仍可能导致请求失败。

有关完整响应字段,请参阅配置状态。

组合健康信号​

请从最早失败的层级开始排查:

信号下一项检查
/livez 或 /readyz 拒绝连接。代理监听器是否已经绑定。对于使用 etcd 或控制面的网关,在应用第一个配置之前它不会绑定;请检查 /status/ready 和配置来源。
/livez 失败。进程状态、监听器绑定和监听器 TLS
/readyz 失败。排空状态
/status/ready 失败。初始配置来源和加载错误
/status/config 为 degraded 或 out_of_sync。被拒绝的资源、来源连接和 last_failure
/status/models 报告 cooldown 或 unhealthy。模型服务提供方凭证、提供方可用性、模型检查和出站网络
所有健康端点均成功,但请求失败。调用方访问权限、模型服务提供方路径、策略执行和上游响应

最后,请使用与应用相同的路径进行检查:

AISIX_API_KEY="YOUR_CALLER_API_KEY"

curl -sS "http://127.0.0.1:3000/v1/models" \
-H "Authorization: Bearer ${AISIX_API_KEY}"

然后通过所需的端点和模型发送真实请求。最后这项探测会验证运行时健康端点刻意不检查的条件。

下一步​

使用故障排除,将失败的健康检查或请求路径检查进一步定位到配置、调用方策略、控制面投射或上游模型服务提供方。