go服务必须绑定127.0.0.1并通过nginx反向代理暴露,proxy_pass需带尾部/,websocket需显式透传upgrade头,静态资源应由nginx直接托管,并设置x-forwarded-proto/for头。

Go 服务不能直接暴露在公网上,必须通过 Nginx 反向代理收口——这是生产部署的硬性前提,不是可选项。
Go 应用必须绑定 127.0.0.1 而非 0.0.0.0
Revel、Gin、Echo 等主流框架默认监听 0.0.0.0:8080,这会让服务直接接受外部连接,绕过 Nginx 的安全控制和 SSL 终止能力。
- 修改配置文件(如
conf/app.conf或代码中http.ListenAndServe参数):确保http.addr = "127.0.0.1",端口设为非特权值(如8089) - 启动时显式指定:例如 Revel 用
revel run -a myapp -p 8089 -c ./conf;Gin 项目改用http.ListenAndServe("127.0.0.1:8080", r) - 验证方式:
ss -tln | grep :8080输出应含127.0.0.1:8080,不含*:8080
proxy_pass 后必须带斜杠,否则路径拼接会出错
Nginx 的 proxy_pass 行为取决于末尾是否有 /,不注意会导致前端路由 404 或静态资源路径错乱。
- 正确写法(推荐):
proxy_pass http://127.0.0.1:8089/;—— 此时location /api/会把请求转发为http://127.0.0.1:8089/api/xxx - 错误写法:
proxy_pass http://127.0.0.1:8089;(无尾部/)——location /api/会转发为http://127.0.0.1:8089/api/xxx,但若后端没做 prefix strip,可能重复解析/api - 若 Go 应用自身已处理所有路径(如 SPA),通常用
location / { proxy_pass http://127.0.0.1:8089/; }即可
WebSocket 支持必须显式启用,否则长连接中断
Revel、Gin 等框架若用到 WebSocket(如实时通知、聊天),Nginx 默认不透传 Upgrade 和 Connection 头,连接会在 60 秒后被关闭。
- 在
location块中补全三行关键头: proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";- 缺一不可,顺序无关;
$http_upgrade是 Nginx 内置变量,不能手写成字面量
静态资源别让 Go 应用扛,Nginx 直接 serve
Go 框架处理静态文件效率远低于 Nginx,且浪费 goroutine。Revel 的 public/、Gin 的 static/ 目录应由 Nginx 托管。
- 添加独立
location块,例如:location ~ ^/(css|js|images|fonts|favicon.ico)/ { root /var/www/myapp/public; expires 1h; add_header Cache-Control "public, immutable"; } - 注意
root路径需指向目录父级(如public所在的上层),不是public本身;否则请求/js/app.js会去找/var/www/myapp/public/js/app.js,而非/var/www/myapp/public/public/js/app.js - 若用
alias替代root,结尾必须加/,且路径语义不同,容易混淆,建议统一用root
最常被跳过的其实是 proxy_set_header X-Forwarded-Proto 和 X-Forwarded-For —— 没它们,Go 应用里 r.Header.Get("X-Forwarded-For") 拿不到真实 IP,req.URL.Scheme 也可能是 http 而非实际的 https,导致重定向循环或权限判断失效。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











