Gin必须监听127.0.0.1而非0.0.0.0,Nginx需透传X-Real-IP与X-Forwarded-For并配置可信代理段,且长连接须同时启用proxy_http_version 1.1和proxy_set_header Connection "",缺一将导致TIME_WAIT暴涨。

Gin 必须绑定 127.0.0.1,不能监听 0.0.0.0;Nginx 必须显式透传 X-Forwarded-For 和 X-Real-IP,否则 c.ClientIP() 永远返回内网地址;长连接要生效,proxy_http_version 1.1 和 proxy_set_header Connection "" 缺一不可——漏掉任一环,TIME_WAIT 就会暴涨。
Go 服务必须监听 127.0.0.1 而非 0.0.0.0
这是生产部署的硬性前提,不是可选项。监听 0.0.0.0 会让 Gin 直接暴露在公网,绕过 Nginx 的 SSL 终止、WAF、限流等所有安全控制层。
- 改代码:把
r.Run(":8080")换成http.ListenAndServe("127.0.0.1:8080", r) - 验证方式:
ss -tln | grep :8080输出中必须含127.0.0.1:8080,不能出现*:8080 - 端口建议选非特权端口(如
8089、9001),避免与系统服务冲突
Nginx 必须正确设置 X-Forwarded-For 和 TrustedProxies
c.ClientIP() 在反代后失效,根本原因是 Gin 默认只信任直连客户端,不解析 X-Forwarded-For,除非你告诉它哪些 IP 是可信代理。
- Gin 启动时必须调用:
r.SetTrustedProxies([]string{"127.0.0.1/32", "192.168.0.0/16"})(按你实际 Nginx 所在网段填) - Nginx 配置里必须加两行:
proxy_set_header X-Real-IP $remote_addr和proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for - 别用
$remote_addr替代$proxy_add_x_forwarded_for:前者会丢掉整条代理链,导致多级代理(如 CDN → Nginx → Gin)下真实 IP 彻底丢失
HTTP/1.1 长连接必须两端同时启用
只配 Nginx 或只靠 Gin 支持都没用。client→Nginx 和 Nginx→Gin 是两条独立链路,必须各自打通。
- Nginx client 端:设
keepalive_timeout 60s(太短易重连,太长易被云 SLB 清掉)和keepalive_requests 2000(按 QPS × 响应时间 × 1.5 估算) - Nginx upstream 端:upstream 块加
keepalive 32;location 块加proxy_http_version 1.1和proxy_set_header Connection ""(注意是空字符串,不是"close"或"keep-alive") - Gin 侧无需额外配置:Go
net/http默认支持 HTTP/1.1 和Connection: keep-alive,但中间件若手动覆写Connection头会导致断连
proxy_pass 末尾斜杠和 WebSocket 透传容易踩坑
路径拼错或 Upgrade 头没透传,前端 404 或 WebSocket 连接 60 秒后静默断开,这类问题排查成本极高。
-
proxy_pass http://127.0.0.1:8080/;(带尾部/):推荐写法,location /api/会转发为/api/xxx,语义清晰 -
proxy_pass http://127.0.0.1:8080;(无尾部/):location /api/会转发为/xxx,后端需做 prefix strip,否则路由错乱 - WebSocket 必须加:
proxy_set_header Upgrade $http_upgrade和proxy_set_header Connection "upgrade",缺一不可
最常被忽略的是 proxy_set_header Connection "" 这一行——它看着像“清空头”,其实是让 Nginx 主动放弃对 Connection 头的干预,把控制权交还给 HTTP/1.1 协议本身。很多线上长连接失效,根源就在这里。


















