883 字
4 分钟
深入解析 NGINX `location` 和 `rewrite` 的进阶实战

一、 location 匹配逻辑:谁才是“最终赢家”?#

NGINX 的 location 指令看似简单,但当多个规则共存时,匹配顺序至关重要。

1. 匹配优先级图解#

NGINX 并不是简单地按照配置文件中从上到下的顺序匹配,而是遵循一套严谨的优先级体系:

匹配符号匹配类型优先级备注
=精确匹配1 (最高)完全匹配 URI,成功后立即停止搜索。
^~最佳前缀匹配2只要匹配到前缀,就不再搜索正则表达式。
~正则匹配(区分大小写)3按配置文件中的先后顺序匹配。
~*正则匹配(不区分大小写)3~ 具有相同优先级。
/通用前缀匹配4 (最低)如果没有其他匹配,则命中此项。

2. 实战示例:配置的最佳实践#

# 1. 首页极致优化:精确匹配提升响应速度
location = / {
proxy_pass http://welcome_page;
}
# 2. 静态资源保护:一旦匹配成功,不再检查正则
location ^~ /static/ {
root /data/web;
}
# 3. 附件处理:不区分大小写的正则匹配
location ~* \.(zip|rar|pdf)$ {
expires 30d;
}
# 4. 默认兜底:处理所有动态请求
location / {
proxy_pass http://app_cluster;
}

二、 rewrite 深度应用:重写与重定向#

rewrite 是流量引导的核心,它的执行过程分为:正则匹配 -> URL 替换 -> 执行 Flag

1. Flag 标志位的“爱恨情仇”#

理解 lastbreak 的区别是区分新手与专家的关键:

  • last:重写 URL 后,重新启动一套新的 location 匹配流程。相当于浏览器重新发起了一个内部请求。
  • break:重写 URL 后,直接在当前的 location 块中处理,不再进行后续匹配。
  • permanent:301 永久重定向(浏览器会缓存),利于 SEO。
  • redirect:302 临时重定向(浏览器不缓存)。

2. 生产环境常用技巧#

场景 A:伪静态处理#

将动态请求伪装成静态 HTML,提升 SEO 排名:

# 将 /product/123 重写为 /api/item?id=123
rewrite ^/product/(\d+)$ /api/item?id=$1 last;

场景 B:旧域名跳转新域名#

server {
listen 80;
server_name old-site.com;
return 301 https://new-site.com$request_uri; # 现代做法推荐 return,效率高于 rewrite
}

三、 高阶进阶:if 指令的“避坑”指南#

在 NGINX 社区中,有一句著名的座右铭:“If is Evil”。如果在 location 块中不当使用 if,可能会导致不可预知的行为。

1. 推荐用法:简单的变量判断#

# 根据移动端展示不同页面
if ($http_user_agent ~* (mobile|nokia|iphone|android)) {
rewrite ^/(.*)$ /mobile/$1 last;
}
# 强制防止跨站请求
if ($http_referer !~* "example.com") {
return 403;
}

2. 为什么说 If 危险?#

因为 if 指令在内部执行时,有时会跳过某些 location 块的上下文,导致 aliasproxy_pass 失效。建议尽可能使用 map 指令或 rewrite 标志位替代复杂的 if 判断。


四、 性能优化与故障排查建议#

  1. 正则效率:正则表达式虽然强大,但会消耗更多 CPU。对于能用前缀匹配(location /path/)解决的场景,不要使用正则。
  2. 避免死循环:使用 last 时,如果规则编写不当导致 URL 反复重写,NGINX 会在循环 10 次后返回 500 错误。
  3. 调试利器:在开发环境开启 rewrite 日志。
error_log /var/log/nginx/error.log notice;
rewrite_log on;

五、 总结#

location 决定了请求“去哪儿”,而 rewrite 决定了请求“长什么样”。通过合理组合这两者,你可以实现极其复杂的灰度发布、动静分离以及流量分发。

深入解析 NGINX `location` 和 `rewrite` 的进阶实战
https://sw.rscclub.website/posts/nginxlocationrewrite/
作者
杨月昌
发布于
2021-08-19
许可协议
CC BY-NC-SA 4.0