GCP中Nginx反向代理Tomcat的健康检查302异常求助
碰到健康检查返回302的情况,大概率是你的Nginx或者后端Tomcat应用在收到请求时触发了重定向规则——毕竟GCP的HTTP健康检查默认不会跟随重定向,只要收到302就会判定为失败。下面是一步步的排查和解决办法:
1. 先手动模拟健康检查请求,定位重定向目标
首先你得搞清楚这个302是跳转到哪里了。在你的实例上(或者任何能直接访问实例80端口的机器),用curl模拟GCP健康检查的请求——一定要带上配置里指定的Host头,因为Nginx是基于Host匹配站点的:
curl -v -H "Host: myapp.com" http://<你的实例内网/公网IP>:80/
看输出里的Location字段,就能知道是跳转到HTTPS、带www的域名,还是应用的某个特定页面了,这是排查的关键第一步。
2. 检查Nginx配置,看是否有全局重定向规则
打开你的Nginx站点配置文件(一般在/etc/nginx/sites-available/myapp.com或者/etc/nginx/nginx.conf里),找有没有类似下面的规则:
- 强制跳转到HTTPS的(比如
return 302 https://$host$request_uri;) - 把裸域名跳转到带www的(比如
if ($host = 'myapp.com') { return 302 http://www.myapp.com$request_uri; }) - 针对根路径
/的特殊重定向
如果有这些规则,你需要给GCP健康检查开个“绿色通道”——因为GCP健康检查的请求会带固定的User-Agent:GoogleHC/1.0,你可以在Nginx里加个判断,让这个请求直接返回200,不触发重定向:
server { listen 80; server_name myapp.com; # 匹配GCP健康检查的请求,直接返回200 if ($http_user_agent = "GoogleHC/1.0") { return 200 "OK"; } # 你的正常重定向规则 return 302 https://$host$request_uri; }
改完配置后记得重启Nginx:sudo systemctl restart nginx
3. 验证后端Tomcat是否返回302
如果Nginx没有重定向规则,那问题可能出在Tomcat的应用上。直接访问Tomcat的8080端口看看:
curl -v -H "Host: myapp.com" http://<你的实例IP>:8080/
如果这里也返回302,说明是应用本身把根路径请求跳转到了其他页面(比如登录页、首页)。这时候最好的办法是修改健康检查的Path,换成应用里专门的健康检查端点——比如很多Java应用会提供/health、/actuator/health这类路径,能稳定返回200状态码。当然你也可以修改应用的根路径逻辑,让它对健康检查请求返回200。
4. 调整GCP健康检查的配置选项
如果上面的方法都不想用,你也可以试试调整健康检查的设置:
- 把Path从
/改成一个能返回200的端点(比如/health),这是最稳妥的做法,因为健康检查应该访问专门的状态接口,而不是业务页面。 - 如果你确实需要用HTTPS,可以把健康检查的Protocol改成HTTPS,Port改成443(前提是你的Nginx配置了HTTPS证书),这样如果重定向是到HTTPS,健康检查就能正常识别了。
5. 确认防火墙是否允许健康检查请求
最后别忘了检查防火墙规则——GCP健康检查的请求来自特定的IP范围,你需要确保实例所在的VPC防火墙允许这些IP访问80端口。最简单的方式是确认有一条允许0.0.0.0/0访问80端口的规则(如果是公网健康检查),或者参考GCP文档添加精准的健康检查IP段。
内容的提问来源于stack exchange,提问作者Thomas Bertoux

