必须使用lua-resty-upstream-healthcheck实现可靠后端健康检查,因其基于ngx_lua异步探测、支持Lua定制策略、动态联动负载均衡并提供可观测性接口。

后端动态健康检查不是简单加个 health_check 指令就能生效的。真正可靠、低干扰、可定制的探测能力,需要借助 OpenResty 生态中成熟稳定的 Lua 库——lua-resty-upstream-healthcheck。它把健康检查从“被动响应”升级为“主动感知”,且全程运行在非阻塞上下文中,不卡主线程、不拖慢请求。
为什么必须用 Lua 实现而非原生 Nginx?
Nginx 开源版本身不支持上游主动健康检查;Plus 版虽有该功能,但配置僵化、扩展性差。而 lua-resty-upstream-healthcheck 基于 ngx_lua 模块,在事件循环内发起异步 HTTP/TCP 探针,复用已有 worker 连接池,零额外进程开销。更重要的是:所有逻辑可写 Lua,比如按 URL 路径区分探活策略、根据响应体内容判断业务层就绪状态、对接内部服务注册中心做双向同步等。
核心配置要点与避坑提示
该模块需在 init_worker_by_lua_block 中初始化,并确保每个 upstream 名称唯一对应一个 checker 实例:
- 避免在
http块全局 init,应按 upstream 分别启动 checker,防止状态混淆 - probe 接口建议走独立管理端口(如 8081),不与业务流量混用,避免探测请求被限流或鉴权拦截
-
shared_dict必须提前声明(如lua_shared_dict healthcheck 10m;),否则 checker 启动失败且无明确报错 - 超时值要明显小于
proxy_read_timeout,例如设为 3s,否则探测本身可能拖累真实请求的超时判定
如何让探测真正“自愈”?关键在状态联动
单纯标记节点为 down 不够,必须让负载均衡器实时感知变化。该模块通过修改 upstream 的 peer 状态实现无缝切换,但前提是 Nginx 配置中启用 least_conn 或 ip_hash 等支持动态剔除的算法,且禁用 down 标记的硬编码(即不要在 upstream 块里写 server x.x.x.x:8080 down;)。
更进一步,可配合 proxy_next_upstream 触发重试:
- 设置
proxy_next_upstream error timeout http_502 http_503 http_504; - 当某节点被 healthcheck 标记为 unhealthy 后,后续新请求不会打过去;若已有请求正在处理中并返回 502/504,Nginx 自动转发到下一个可用 peer
- 节点恢复后,checker 会自动将其重新纳入调度池,无需 reload 配置
可观测性不能少:暴露健康状态供监控接入
模块内置 /healthz 或自定义 endpoint(通过 lua_content_by_lua_block),可输出结构化 JSON,包含各 upstream 下每个 server 的当前状态、连续失败次数、最后探测时间等字段。建议将此接口接入 Prometheus + Grafana,设置告警规则如“单 upstream 健康率低于 90% 持续 2 分钟”。
日志方面,开启 lua_log_level warn; 并捕获 healthcheck 相关 log,便于快速定位是网络不通、证书过期还是业务返回异常码。


















