Nginx proxy_pass用IP能通而域名报502,本质是Host请求头未正确透传导致后端(如Workerman)路由或校验失败:Nginx默认不覆盖Host头,若配置中缺失proxy_set_header Host $host;,后端收到的是IP而非访问域名,触发代码中Host比对拦截、WebServer addRoot()拒绝响应或空返回,Nginx据此判定为无效响应而返回502。

域名访问报502,但直接用IP能连上Workerman,说明问题出在反向代理层与域名路由的配合上,不是Workerman本身挂了。
为什么Nginx proxy_pass到IP能通,换成域名就502?
这本质是「请求头 Host 字段」和「后端服务路由逻辑」不匹配导致的。Workerman 默认不校验 Host,但如果你在代码里用了 $connection->getHeader('Host') 做分流、或启用了 WebServer 模式并绑定了特定域名,而 Nginx 的 proxy_pass 没透传/覆盖 Host,后端就可能拒绝响应或返回空内容——Nginx 收到空响应就判为 502。
常见触发点:
- Nginx 配置里漏了
proxy_set_header Host $host;,导致后端收到的 Host 是 IP 地址(如192.168.1.100),而非你访问的域名(如api.example.com) - Workerman 的 HTTP Server 实例监听了
0.0.0.0:2346,但业务逻辑里写了if ($request->header['Host'] !== 'api.example.com') { exit; } - 用了 Workerman 的
WebServer类且设置了$webserver->addRoot('example.com', '/var/www');,但 Nginx 转发时 Host 不匹配,直接 404 或空响应 → Nginx 升级为 502
检查Nginx error.log里的关键线索
502 错误本身不告诉你原因,但 Nginx 的 error.log 会暴露真实失败点。打开日志,搜这几行:
-
upstream prematurely closed connection:后端主动断连,大概率是 PHP/Workerman 进程崩溃或超时退出 -
Connection refused:Nginx 根本连不上后端地址,确认proxy_pass http://127.0.0.1:2346;中的端口是否真被 Workerman 监听(netstat -tuln | grep :2346) -
upstream sent no valid HTTP/1.0 header:后端返回了非 HTTP 格式内容(比如 Workerman 启动失败打印了 warning 文本,或 JSON 直出没包 HTTP 头)
特别注意:如果日志里出现 recv() failed (104: Connection reset by peer),八成是 Workerman 收到非法 Host 后直接 close 了连接。
Workerman侧必须确认的3个配置点
Workerman 本身不内置域名路由,但你写的代码或加载的组件会依赖它。务必检查:
-
Worker::listen('http://0.0.0.0:2346')是否写死绑定 IP,应改为'http://0.0.0.0:2346'或'http://127.0.0.1:2346',避免监听 localhost 导致外部 Nginx 无法回环 - 是否在
onMessage里手动解析$_SERVER['HTTP_HOST']或$request->header['Host']并做了跳转/拦截,却没兼容127.0.0.1或空 Host - 是否启用了
WebServer并调用了addRoot()—— 它内部会严格比对 Host,不匹配就返回空响应,Nginx 看到空就报 502
快速验证:用curl绕过浏览器和Nginx直测
在服务器本地执行这两条命令,对比输出差异:
curl -H "Host: api.example.com" http://127.0.0.1:2346/health
curl -H "Host: 127.0.0.1" http://127.0.0.1:2346/health
如果第一条返回正常 JSON,第二条返回空或 404,就坐实是 Host 校验问题;如果两条都空,说明 Workerman 进程根本没正确启动或监听错端口。
这个步骤能排除 DNS、浏览器缓存、HTTPS 重定向等干扰,直击核心链路。
真正卡住人的地方,往往不是 Workerman 启没启,而是 Nginx 和 Workerman 对「同一个请求该长什么样」的理解不一致——尤其是 Host 头、协议版本、连接复用这几个字段。差一个字母,就从 200 变成 502。

















