先看现象。阿里云 SLB 七层监听,后端 nginx 上跑着两个域名站点,健康检查路径配的是 /healthz,后端 access log 一直返回 404,控制台显示后端异常,直接 curl 后端 IP 的 /healthz 却是 200。

排查方向其实有限,先把可能性排一排。健康检查没有带 Host 头,请求落到了默认站点。也可能是默认 server 块里没有 /healthz 这个 location。

少数情况下是后端按 server_name 匹配域名,用 IP 访问被拒。

不容易想到的是,健康检查路径写错,多了或少了一层前缀。

上来先看健康检查请求落到了哪个站点

tail -f /var/log/nginx/access.log | grep healthz

再往下按 SLB 的方式手动请求验证

curl -H 'Host: www.example.com' http://10.0.0.12/healthz -i

给默认站点补一个健康检查入口

printf 'location = /healthz { return 200 "ok"; }\n' > /etc/nginx/conf.d/health.conf

等前面都确认过,再检查语法并平滑重载

nginx -t && nginx -s reload

怎么算真的好了,看的是同一批现象。后端 access log 里健康检查返回 200,SLB 后端状态变成正常,流量重新分发到该节点。

这里还有个坑。七层健康检查一定要配 Host,否则请求全落到默认站点;四层检查只看端口通不通,查不出应用层假死。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189