2.2 访问报错:502 / 504 / 404 与反向代理排错
先给一个判断
502 是“后端没接电话”,504 是“后端接了电话没说话”,404 是“前台找不到这个分机号”。 三个码对应请求路径上三个不同的故障点,弄清这一点,排错方向就不会错。OpenResty 是前台,后端是你的应用或运行环境;前台能正常响应,说明 OpenResty 本身没事,去查它背后的东西。
现象速查表:先对号入座
| 状态码 | 含义 | 最可能的原因 | 排查起点 |
|---|---|---|---|
| 502 | 网关错误 | 后端服务挂了 / 没监听对端口 | 后端容器或进程状态 |
| 504 | 网关超时 | 后端太慢,代理等不及 | 后端性能、超时配置 |
| 404 | 找不到 | 路径不对 / 代理地址错 / 默认文档缺失 | 网站目录与代理配置 |
| 502 间歇出现 | 时好时坏 | 后端负载高或频繁重启 | 后端日志、监控 |
| 全站 502(所有网站) | 一起挂 | OpenResty 自身异常 | OpenResty 状态与日志 |
记住 02-0 里的规律:全挂先看 OpenResty,单个挂先看那个网站的配置和日志。
定位:从错误日志开始
入口:日志审计 → 网站日志,选一个网站,看 OpenResty 的错误日志。错误日志会明确写出类似“connection refused while connecting to upstream”或“upstream timed out”这样的原文,直接指向问题。
在服务器上也可以直接看:
# 找到 OpenResty 容器(具体名称以应用商店安装的为准)
docker ps --filter "name=openresty"
# 看最近的错误日志(容器名按实际替换)
docker logs --tail 100 1panel-openresty 2>&1 | grep -i "error\|upstream"
一个真实的工作习惯:开两个浏览器标签,一个看错误日志,一个改配置。改一次,切过去看日志有没有新报错,比“改了试、试了再猜”快十倍。
修复:502 —— 后端没接电话
第一步:确认后端在不在。
# 运行环境类网站:查后端进程/容器
docker ps | grep -E "php|node|java|python"
# 一键部署类网站:查应用容器
docker ps | grep -i wordpress
容器是 Exited 或 Restarting 状态,先看它的日志找死因:
docker logs --tail 200 容器名
第二步:确认端口对不对。 后端进程活着,但 OpenResty 找的是另一个端口,照样 502。在网站配置的“反向代理”或创建时的代理地址里核对。
# 本地直连后端端口验证(绕过 OpenResty)
curl -I http://127.0.0.1:后端端口/
本地能通,说明是 OpenResty 到后端的配置问题;本地不通,后端自己有问题。
第三步:容器网络。 后端跑在容器里、OpenResty 也跑在容器里,两者不在同一个 Docker 网络时,127.0.0.1 可能互相够不着。用容器名/服务名访问,或者检查网络设置(容器网络排错见 3.3 节)。
修复:504 —— 后端太慢
504 是后端有能力响应,但超过代理的超时时间。两个方向:
| 方向 | 动作 |
|---|---|
| 治标 | 在网站配置的反向代理中调大超时时间 |
| 治本 | 查后端为什么慢:数据库慢查询、PHP 进程数不够、内存不足 |
后端慢的根因往往不在网站这边。PHP 网站可以先查运行环境的进程守护配置和 PHP 配置;数据库慢查询看数据库设置里的慢日志(见 4.3 节)。
边界提醒:调超时只是给后端更多时间,如果后端本来就慢到 60 秒,调到 120 秒只是让用户多等一分钟。先定位慢在哪。
修复:404 —— 分两种情况
情况 A:静态网站 / 运行环境网站报 404。 先确认文件真的在那儿:
# 进网站目录看文件在不在(路径换成你的网站目录)
ls -la /opt/1panel/www/sites/你的网站/index/
再看默认文档配置(网站配置 → 默认文档),里面的文件名要和实际入口文件一致,顺序也有讲究——index.html 在前就不会去加载 index.php。
情况 B:反向代理网站报 404。 问题几乎都在代理路径上。核对两点:
- 代理地址对不对(含端口、含路径前缀);
- 后端服务的路由是否认识传过去的路径。
典型例子:前端代理到 http://127.0.0.1:3000,但前端应用部署在 /app 路径下,访问 你的域名/app 才行,访问根路径自然 404。
情况 C:负载均衡的坑。 网站配置里可以建负载均衡规则,把请求转到多个后端。创建反向代理时代理地址要写成 http://<负载均衡名称> 才会真正生效。如果Load balance 建了但代理地址还是指向单台后端,请求根本不会分流,某台后端挂了就直接 502,而你还以为有高可用。去网站配置的负载均衡和反向代理两个页面对一遍。
反向代理的两个经典坑
坑一:WebSocket 不通
官方 FAQ 明确记载:用自建 Nginx 反向代理 1Panel(或任何依赖 WebSocket 的服务),必须加上这三行,否则面板终端、容器终端这类功能全部用不了:
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
官方还给了个偷懒办法:直接在 1Panel 里新建一个反向代理网站,这些都自动带上。
坑二:跨域(CORS)报错
前后端分离部署时,浏览器控制台报 CORS policy 开头的错误,是跨域拦截。在网站配置的 CORS 页面配置允许来源、方法、请求头。
一个硬规则:允许携带凭证(Cookie)时,允许来源不能配成通配的 *,必须写具体的域名。这是浏览器的规范,不是 1Panel 的限制。详见 2.4 节。
一个完整的复现与修复
现象:WordPress 网站突然全站 502,首页都打不开。
排查过程:
- 先确认是不是全挂——同服务器另一个静态网站访问正常。排除 OpenResty,锁定这个网站的后端。
- 看网站日志的错误日志,反复出现“connection refused”,后端连不上。
docker ps发现 PHP 运行环境容器是Exited状态,docker logs显示内存不足被杀。
修复:服务器内存本来就紧张,先重启运行环境恢复网站,然后把 PHP 的进程数调小一点,并整治占内存的数据库(过程见 4.3 节),之后没再复发。
复盘要点:502 的第一动作永远是“看是不是全挂”,这一个动作就能决定后面查 OpenResty 还是查后端。
验证
# 1. 确认状态码(-I 只看头)
curl -I http://你的域名/
# 2. 模拟 Host 头访问(域名没解析时也能测)
curl -I -H "Host: 你的域名" http://服务器IP/
# 3. 本地直连后端
curl -I http://127.0.0.1:后端端口/
第 2 条特别有用:域名解析还没生效或者用 CDN 时,用 Host 头能直接测到 OpenResty 的真实响应,bypass 掉 DNS 和 CDN 的干扰。
还有一个容易被忽略的验证点:改完网站配置要点保存,然后观察是否需要重载 OpenResty。OpenResty 的“重载”按钮在网站列表上方工具栏,不停机应用新配置;如果配置改了但没生效,先确认这一步做了没有。
本节要点
- 502 查后端死活,504 查后端速度,404 查路径和代理地址;
- 全站挂看 OpenResty,单个挂看那个网站的配置和日志;
- 反代 WebSocket 必须加
Upgrade/Connection头,官方 FAQ 有原文; - CORS 带凭证时来源不能配
*; - 排错时善用
curl -H "Host: ..."绕过 DNS。
网站配置的各项入口(域名、目录、默认代理、CORS、伪静态等)都在网站列表的【配置】里,详见 1Panel 官方文档:网站配置。
下一节:网站能打开了,但 HTTPS 证书申请不下来、快到期了也没续上——域名解析和证书的坑,一个比一个隐蔽。
