给自己的几个小服务配反向代理,同一个问题反复踩了三遍,这次写下来彻底了结。
主要集中在 proxy_pass 的路径拼接规则,以及静态文件和代理混用时的目录设置。
一、末尾斜杠决定路径怎么拼
这是最容易混淆的一点。假设有如下配置:
location /api/ {
proxy_pass http://127.0.0.1:8000;
}
此时请求 /api/users 转发到后端的是 /api/users,原样保留。
因为 proxy_pass 的 URL 部分没有路径(没写斜杠后的部分),Nginx 只做协议和地址替换。
location /api/ {
proxy_pass http://127.0.0.1:8000/;
}
加了末尾斜杠,location 匹配到的 /api/ 前缀会被 替换 掉,
请求 /api/users 到后端变成 /users。同一个字符,行为完全相反。
记忆口诀:
proxy_pass带路径(哪怕只是一个/)就替换前缀,不带就原样透传。
二、root 与 alias 的区别
托管静态文件时这两个指令长得像,用法不一样:
# root:把 location 的路径一并拼到目录后面
location /images/ {
root /var/www;
}
# 请求 /images/a.png → 实际读 /var/www/images/a.png
# alias:用目录整体替换 location 匹配的部分
location /images/ {
alias /var/www/static/;
}
# 请求 /images/a.png → 实际读 /var/www/static/a.png
alias 的目录末尾斜杠要和 location 的末尾斜杠对齐,否则会拼出奇怪的路径。
自己的场景里 root 用得更多,目录结构简单就不容易错。
三、SSE / 流式接口要关掉缓冲
做聊天类的流式输出时,如果发现前端要等很久才一次性收到全部内容, 基本都是 Nginx 的代理缓冲在作怪。加上这几行:
location /api/v1/chat/stream {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 600s;
}
proxy_buffering off 让响应边收边发,proxy_read_timeout 调大
是为了防止长时间没数据时连接被中途掐断。
四、改完一定要检查语法
nginx -t # 检查配置语法,通过了才 reload
nginx -s reload # 平滑重载,不中断现有连接
nginx -t 这一步别省。配置写错直接 reload,
可能整个站一起不可用,排查起来反而更费时间。
小结
proxy_pass带不带路径,决定路径替换还是原样透传。root是拼接,alias是替换,末尾斜杠要对齐。- 流式响应记得
proxy_buffering off并放宽超时。 - 改配置先
nginx -t,再 reload。