Iris项目502错误主因是Nginx配置三要素错位:upstream必须置于http{}顶层、proxy_pass须严格匹配upstream名且无路径、后端Iris服务端口需真实就绪并互不冲突。

直接说结论:Iris 项目用 Nginx 做反向代理 + 多节点负载均衡,关键不是 Iris 本身怎么写,而是 Nginx 的 upstream 定义位置、proxy_pass 指向方式、以及后端服务启动端口是否真实就绪——三者错一个,502 Bad Gateway 就立刻出现。
upstream 必须写在 http{} 顶层,不能塞进 server 块里
很多人把 upstream 块复制粘贴到某个 server 配置内部,reload 时 nginx 直接报错:unknown directive "upstream"。这是因为 upstream 是全局指令,只允许出现在 http{} 范围内(比如 /usr/local/nginx/conf/nginx.conf 的 http 段开头,或通过 include 引入的独立文件中)。
正确写法示例:
http {
upstream iris_backend {
server 127.0.0.1:1213;
server 127.0.0.1:1511;
}
include /usr/local/nginx/conf/vhosts/*.conf;
}
错误写法(哪怕语法能过,也无法被引用):
server {
listen 80;
server_name iris.app.com;
upstream iris_backend { ... } ← 这里会报错,且 proxy_pass 找不到它
}
proxy_pass 必须严格匹配 upstream 名,且不能带路径
proxy_pass 后面跟的是 upstream 名称,不是 URL 路径。常见错误是:
- 拼错名字:定义了
upstream iris_backend,却写了proxy_pass http://iris_backed(少个n) - 多加斜杠:
proxy_pass http://iris_backend/→ 触发upstream cannot have URI错误 - 混用 IP 和 upstream:
proxy_pass http://127.0.0.1:1213写死单点,等于放弃负载均衡
正确配置片段:
server {
listen 8000;
server_name iris.app.com;
location / {
proxy_pass http://iris_backend; ← 注意:无协议头以外的任何字符,无尾部斜杠
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
后端 Iris 服务必须提前启动且端口不冲突
Iris 默认不自动重试绑定端口,如果两个实例都试图监听 :1213,第二个会直接 panic 报错退出,Nginx 却还在往它身上转发请求,结果就是持续 502。
启动多个 Iris 实例时务必确认:
- 每个
app.Run(iris.Addr(":xxxx"))的端口号互不相同(如:1213、:1511、:1811) - 进程确实在运行:
lsof -i :1213或ss -tuln | grep 1213 - 没被防火墙拦截(尤其是 CentOS/RHEL 系统的
firewalld或iptables)
建议在 main.go 开头加一行日志输出,比如 app.Logger().Infof("Server started on %s", addr),方便确认是否真跑起来了。
健康检查和超时要显式配,别信默认值
默认轮询下,只要某个 Iris 实例卡住(比如 goroutine 死锁、数据库连接池耗尽),Nginx 仍会继续发请求过去,用户看到的就是长等待或 504。必须加基础保护:
-
max_fails=2:连续失败 2 次就临时剔除该节点 -
fail_timeout=5s:5 秒内不往它转发新请求 -
proxy_connect_timeout 3s:建立 TCP 连接最多等 3 秒 -
proxy_read_timeout 10s:等待后端响应最多 10 秒
完整 upstream 示例:
upstream iris_backend {
server 127.0.0.1:1213 max_fails=2 fail_timeout=5s;
server 127.0.0.1:1511 max_fails=2 fail_timeout=5s;
}
真正容易被忽略的是:这些参数不写,Nginx 就不会做主动探活;而 Iris 自身没有内置 HTTP 健康检查 endpoint,你得自己加一个 GET /health 路由并返回 200,再配合第三方工具(如 consul-template 或自定义脚本)做更精细的节点管理。











