Nginx 的 map + rewrite 组合是旧 API 无损迁移首选方案:map 在 http 块预定义路径映射,rewrite 在 location 中用 last 触发内部重定向,配合 proxy_pass 转发至新版服务,实现客户端无感、低延迟、可灰度的平滑下线。
旧 API 下线前,最稳妥的方式不是直接停用,而是把所有旧路径自动、精准地映射到新服务地址——Nginx 的
+
组合,正是为此类无损迁移量身定制的方案。它不依赖后端改代码,不增加代理跳转延迟,还能按规则精细控制,是灰度下线与路径重构的首选手段。
用 map 预定义路径映射关系,清晰可维护
指令在 Nginx 全局作用域(通常写在
块)中建立键值映射,将旧路径前缀映射为对应的新路径前缀或目标服务标识。它只做字符串匹配,不触发重写,开销极低,且支持正则、默认值和嵌套判断。
例如,将三类旧 API 前缀分别导向不同新版路径:
匹配顺序从上到下,第一个成功匹配的规则生效;
表示未匹配时留空,便于后续判断
正则捕获组
保留原始参数,确保 query string 自动透传
变量名
是自定义的,语义明确,方便后续逻辑复用
用 rewrite 按需触发内部重写,保持客户端无感
在 server 或 location 块中,通过
指令检查
是否非空,仅当有映射结果时才执行内部重定向。关键在于使用
标志,让 Nginx 重新匹配 location,走新路径的处理逻辑(比如 proxy_pass 到新版服务),而浏览器 URL 不变。
Nginx
在宝塔面板中轻松管理Nginx高性能Web服务器。提供可视化配置反向代理、负载均衡、SSL证书及HTTP缓存功能,一键优化高并发性能,助您高效搭建稳定、快速的网站运行环境。
下载
避免在
中直接写
(Nginx 官方不推荐),先用 map 计算好再判断,更安全稳定
是核心:它终止当前 location 匹配,用新 URI 再次查找 location,实现“路径替换+逻辑切换”一体化
末尾
是兜底策略,防止遗漏规则导致旧接口意外暴露
配合 proxy_pass 转发到新版服务,隐藏真实后端
新版路径(如
)需由独立 location 捕获,并转发至实际服务。此时可结合 upstream 实现负载均衡或健康检查,与旧路径解耦。
末尾带斜杠
,表示截断前缀,否则路径会原样拼接(如
+ 请求
→ 后端收到
)
所有 header 透传确保后端能获取真实客户端信息,便于日志、鉴权等处理
不同版本路径可指向不同 upstream,天然支持灰度发布与流量切分
验证与上线前的关键检查点
上线前必须逐项确认,避免 500、循环重写或静默失败:
用
检查语法,特别注意 map 变量是否在 http 块定义、rewrite 是否在正确上下文
开启
,观察是否有 “rewrite or internal redirection cycle” 报错
用 curl 测试典型路径:
,确认响应头
和 body 来自新版服务,且状态码为 200
检查 access log 中旧路径是否全部被重写,无残留 404 或直接命中旧后端的日志
maprewritemaphttp
map $uri $new_path {
default "";
~^/api/v1/users/(.*)$ /api/v2/profiles/$1;
~^/api/v1/orders/(.*)$ /api/v3/transactions/$1;
~^/api/v1/products/(.*)$ /api/v2/items/$1;
}
default ""(.*)$new_pathrewrite$new_pathlast
location /api/v1/ {
if ($new_path != "") {
rewrite ^(.*)$ $new_path last;
}
return 404; # 无匹配则拒绝旧路径访问
}
ifrewritelastreturn 404/api/v2/profiles/...
location /api/v2/ {
proxy_pass https://backend-v2/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api/v3/ {
proxy_pass https://www.php.cn/link/720a860f1a870a7f103b2518f7f9843a;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
proxy_pass/proxy_pass http://b//api/v2/x/xnginx -terror_log /path/to/error.log notice;curl -v http://your.domain/api/v1/users/123Server