beego默认监听根路径,nginx的proxy_pass末尾必须加/,否则路径错位导致404;upstream必须定义在http块顶层,不可置于server内;需透传x-real-ip等header并配置健康检查兜底。

Beego 默认监听根路径,Nginx 的 proxy_pass 末尾必须加 /,否则所有接口 404;upstream 块不能写在 server 内,否则 reload 报错“unknown directive”。
Beego 路由与 proxy_pass 斜杠必须对齐
Beego 的路由注册(如 beego.Router("/health", &HealthController{}))默认从 / 开始匹配,不带前缀。若 Nginx 配置为:
location /api/ {
proxy_pass http://beego_backend;
}
请求 /api/health 会原样发给 Beego —— 它收不到 /health,只注册了 /health,结果 404。
正确做法是让 Nginx 剥离 /api/ 前缀:
-
location /api/ { proxy_pass http://beego_backend/; }→ 请求/api/health被重写为/health发往 Beego -
location / { proxy_pass http://beego_backend/; }→ 所有请求直通,最简且推荐 - 绝对不要混搭:
location /api { proxy_pass http://beego_backend/; }(location无尾斜杠 +proxy_pass有),会导致路径拼接异常,比如变成//health
upstream 必须定义在 http{} 顶层
Nginx 解析时,upstream 是全局指令,只允许出现在 http 块内。常见错误是把它塞进某个 server 块里,reload 时直接报:
nginx: [emerg] unknown directive "upstream" in /etc/nginx/conf.d/beego.conf:12
正确结构:
http {
upstream beego_backend {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
least_conn;
keepalive 32;
}
<pre class="brush:php;toolbar:false;">server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://beego_backend/;
# ... 其他 proxy_* 指令
}
}}
- 多个 Beego 实例需监听不同端口(如
:8080,:8081),避免端口冲突 -
least_conn比默认轮询更合理,尤其 Beego 处理耗时差异大时 -
keepalive 32复用连接,降低 Beego 侧 TIME_WAIT 压力
Beego 获取真实客户端 IP 必须靠 Nginx 透传
Beego 默认用 c.Ctx.Input.IP() 拿到的是 Nginx 的本地地址(如 127.0.0.1)。要拿到真实 IP,两处缺一不可:
- Nginx 配置中加三行:
proxy_set_header X-Real-IP $remote_addr;、proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;、proxy_set_header X-Forwarded-Proto $scheme; - Beego 代码里改用:
c.Ctx.Request.Header.Get("X-Real-IP")或更稳妥的c.Ctx.Input.IP()(它内部已兼容X-Forwarded-For多级解析) - 别漏
proxy_set_header Host $host;,否则 Beego 的urlfor生成链接可能丢失域名
如果用了 beego.BConfig.Listen.HTTPPort = 8080 但没关掉 beego.BConfig.Listen.EnableHTTP = true,确保 Nginx 没连错端口或协议。
健康检查不能只靠轮询
开源 Nginx 不支持主动健康检查(health_check 是 Plus 商业功能),只能靠被动检测:
- 每个
server行必须加max_fails=3 fail_timeout=30s,否则挂掉的 Beego 实例还会持续收请求,拖垮整体 - 示例:
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s; - 若需主动探测,得编译安装
nginx_upstream_check_module,并在upstream块里加check interval=3 rise=2 fall=5 timeout=1 - Beego 自带
/healthz接口(需启用beego.BConfig.HealthCheckPath = "/healthz"),正好用作探测目标
路径拼接、upstream 位置、header 透传、健康兜底——这四点漏掉任一,Beego 就可能收不到请求、拿不到 IP、无法均衡或持续转发到死节点。不是 Beego 有问题,是 Nginx 那层没对齐它的行为假设。











