nginx动态路径转发需结合正则location捕获、rewrite重写uri、proxy_pass无尾斜杠转发;若proxy_pass含变量域名,必须配置resolver实现动态dns解析。

Nginx 中可以通过 proxy_pass 结合 location 的正则匹配与 rewrite 指令,实现动态路径重写后转发。关键在于:正则捕获路径片段 → 用 rewrite 重写 URI → proxy_pass 转发重写后的路径(且末尾不带 /,否则会丢弃原始路径)。
使用正则 location 捕获路径并 rewrite
当需要根据路径结构提取变量(如版本号、租户 ID、服务名)并改写为后端可识别格式时,推荐用 ~ 或 ~* 开头的正则 location:
-
location ~ ^/api/v(\d+)/(.+)$ {—— 捕获版本号$1和子路径$2 - 配合
rewrite ^/api/v\d+/(.+)$ /$1 break;将/api/v2/users改写为/users -
proxy_pass http://backend;此时转发的是重写后的 URI(/users),不是原始路径
proxy_pass 末尾斜杠决定路径拼接逻辑
这个细节极易出错:
-
proxy_pass http://backend;(无尾部/)→ 原始请求 URI(或 rewrite 后的 URI)**完整保留**,追加到后端地址后 -
proxy_pass http://backend/;(有尾部/)→ Nginx **丢弃匹配的 location 前缀**,只把剩余路径拼在/后 - 若用了
rewrite ... break;,则以 rewrite 后的 URI 为准;若用rewrite ... last;,会重新匹配 location,需谨慎
带变量的 proxy_pass(需搭配 resolver)
如果后端地址本身要动态化(如基于域名或 header 决定目标),可结合 set + 变量 proxy_pass:
-
set $backend "http://svc-$tenant.example.com";($tenant 来自 header、cookie 或 rewrite 捕获) -
proxy_pass $backend;—— 注意:此时必须配置resolver(如resolver 8.8.8.8 valid=30s;),否则变量域名无法解析 - 该方式不依赖 rewrite,但要求后端服务支持对应 host 头,通常还需加
proxy_set_header Host $host;
完整示例:按租户前缀路由并剥离
将 /t-abc/api/users 转为 /api/users 并转发至对应租户后端:
location ~ ^/t-(\w+)/(.*)$ {
set $tenant $1;
set $path $2;
rewrite ^/t-\w+/(.*)$ /$1 break;
resolver 127.0.0.11 valid=5s; # Docker DNS 或实际 DNS
proxy_pass http://svc-$tenant.internal;
proxy_set_header Host svc-$tenant.internal;
}
注意:rewrite ... break 确保不循环匹配;resolver 是变量域名解析必需项;Host 头显式设置便于后端识别租户。











