Nginx 的 map 指令可基于 $uri 或 $request_uri 动态映射 upstream 名称,需在 http 块定义、location 中用 proxy_pass http://$backend(不带路径),配合 rewrite 实现路径剥离,支持正则匹配与 default 回退。
Nginx 的
指令可用于根据请求路径(如
或
)动态设置变量值,再结合
引用该变量,实现后端 up
stream
的灵活切换。关键在于变量必须在
外定义、作用域正确、且
使用变量时不能带 URI 路径。
定义 map 块匹配路径并映射 u
ps
tream 名称
在
块中使用
,基于
(标准化路径,不含参数)或
(含查询参数)做精确/前缀/正则匹配,将结果赋给自定义变量(如
):
用
开头表示区分大小写的正则匹配,
表示不区分大小写
支持
设置默认 upstream,避免未匹配时变量为空导致 502
路径匹配建议优先用
,更稳定;需匹配带参路径时才考虑
示例:
稿定在线PS
PS软件网页版
下载
在 location 中通过变量调用对应 upstream
在
或
块中,用
—— 注意:
不能加路径后缀
(如
),否则 Nginx 会忽略变量,报错或回退到字面量解析。
若需重写路径,用
或
配合
不带路径的方式
确保
变量已定义且拼写一致,Nginx 启动时会校验 upstream 是否存在
可配合
等保持原始请求头
示例:
处理路径重写与前缀剥离
当不同 upstream 期望的入口路径不一致时(如
应转发到 users 服务的
),需在匹配后剥离前缀:
用
提前改写
,再交给
匹配(适合规则简单、统一剥离)
更推荐:在
内用
+
,但会失去 map 的集中管理优势
折中方案:map 中仍按原始路径匹配,再用
+
组合实现路径转换
例如,将
转发到
的
:
验证与调试技巧
配置完成后务必测试,常见问题可通过以下方式定位:
运行
检查语法;启动后用
观察响应头和状态码
开启
查看 map 变量实际取值(需编译时含 debug 日志支持)
临时添加
到 location,直接从响应头确认路由是否生效
注意:map 不支持嵌套或复杂逻辑,超出现有功能建议改用 Lua(via lua-nginx-module)或外部服务路由
map$request_uri$uriproxy_passlocationproxy_passhttpmap$uri$request_uri$backend~~*default$uri$request_urihttp {
map $uri $backend {
default backend_default;
~^/api/v1/users backend_users;
~^/api/v1/orders backend_orders;
~^/admin backend_admin;
/healthz backend_monitor;
}
upstream backend_default { server 10.0.1.10:8080; }
upstream backend_users { server 10.0.1.20:8080; }
upstream backend_orders { server 10.0.1.30:8080; }
upstream backend_admin { server 10.0.1.40:8080; }
upstream backend_monitor { server 127.0.0.1:9090; }
}serverlocationproxy_pass http://$backendhttp://$backend/apirewriteproxy_rewriteproxy_pass$backendproxy_set_header Host $host;server {
listen 80;
server_name example.com;
location / {
proxy_pass http://$backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}/api/v1/users/rewrite$urimaplocationrewrite ^/api/v1/(.*)$ /$1 break;proxy_pass http://backend_users;proxy_passrewrite/api/v1/users/xxxbackend_users/xxxlocation ~ ^/api/v1/users(/|$) {
rewrite ^/api/v1/users(/?)(.*)$ /$2 break;
proxy_pass http://backend_users;
}nginx -tcurl -v http://localhost/xxxerror_log /var/log/nginx/error.log debug;add_header X-Backend $backend;