nginx老旧系统平移需用rewrite last+proxy_pass带/实现无感转发:rewrite last触发新location匹配,proxy_pass末尾/剥离前缀,避免循环需分离源目路径,静态/api资源应分类处理并透传必要头。

在老旧系统平移过程中,用 Nginx 的 rewrite 配合 proxy_pass,可以做到 URL 路径重写 + 后端透明转发,用户不改链接、不感知迁移,后端服务也无需修改路径逻辑 —— 关键在于 rewrite 的执行时机、flag 控制和 proxy 中的路径处理要协同一致。
rewrite 必须用 last(而非 break)才能进 proxy_pass 流程
Nginx 的 rewrite 指令默认在 server 或 location 块中执行,但它的后续行为取决于所用 flag:
- last:终止当前 location 匹配,用重写后的新 URI 重新匹配 location —— 这是实现“重写后走代理”的必要条件;
- break:停止 rewrite,直接用当前 URI 执行本 location 内后续指令(如 proxy_pass),但不会重新匹配,容易导致路径错位;
- redirect / permanent:返回 302/301,用户可见跳转,不符合“无感知”要求,应避免。
✅ 正确示例(将 /old-app/xxx 无感映射到新后端的 /api/xxx):
location ^~ /old-app/ {
rewrite ^/old-app/(.*)$ /api/$1 last;
}
location /api/ {
proxy_pass http://backend-service/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
注意:proxy_pass 末尾带 /,表示截断前缀 /api/,只把 $1 部分发给后端;若不加 /,则整个重写后的 URI(含 /api/)会原样透传,后端需能处理该前缀。
避免 rewrite 循环:location 匹配范围要精准
如果 rewrite 后的新 URI 又命中了同一个 location(比如都匹配 /old-app/),就会触发无限循环,Nginx 会报 rewrite or internal redirection cycle 错误。
解决方法:
- 用
^~前缀让 location 匹配更明确(优先级高于正则,且不参与重匹配); - rewrite 目标路径(如
/api/)必须由另一个独立 location 处理,且不能和源 location 重叠; - 必要时用
location = /old-app单独处理根路径,防止/old-app被/old-app/location 意外捕获。
后端真实路径兼容性:proxy_pass 的斜杠决定是否透传前缀
这是最容易出错的点。proxy_pass 的结尾斜杠,控制着 Nginx 是否剥离 location 前缀:
-
proxy_pass http://upstream/;(末尾有/)→ 剥离匹配的 location 前缀,只转发 path 剩余部分; -
proxy_pass http://upstream;(无斜杠)→ 把完整重写后的 URI(含前缀)原样转发。
举例:
location /old-app/ {
rewrite ^/old-app/(.*)$ /v2/$1 last;
}
location /v2/ {
proxy_pass http://new-svc/; ← 剥离 /v2/,后端收到 /user/list
}
若写成 proxy_pass http://new-svc;(无斜杠),后端实际收到的是 /v2/user/list,需确保后端路由支持 /v2/ 前缀。
补充:静态资源与 API 分离时的路径对齐
老旧系统常混用 HTML、JS、CSS 和接口,迁移时建议按类型拆分处理:
- HTML 页面:用 rewrite + proxy_pass 转发到新服务的渲染入口;
- 静态资源(
/static/,/assets/):可直接 alias 到新目录,或用单独 upstream 回源; - API 接口(
/api/,/rest/):统一 rewrite 到新后端,并确保鉴权头(如 Cookie、Authorization)透传。
例如兼容老前端发起的 /rest/user 请求:
location ^~ /rest/ {
rewrite ^/rest/(.*)$ /api/v1/$1 last;
}
location /api/v1/ {
proxy_pass http://api-backend/;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-Prefix "/rest";
}
加 X-Forwarded-Prefix 是为后端生成正确跳转链接或资源路径提供依据(尤其涉及重定向或 HATEOAS 场景)。











