乐闻世界logo
搜索文章和话题

Nginx 的 location 指令如何匹配?优先级是什么?

2月21日 16:56

Nginx 的 location 指令如何匹配?优先级是什么?

Nginx 的 location 指令用于匹配请求的 URI,并定义如何处理这些请求。理解 location 的匹配规则和优先级对于正确配置 Nginx 至关重要。

Location 匹配规则:

1. 精确匹配(=)

使用 = 进行精确匹配,如果匹配成功,立即停止搜索并使用该 location。

nginx
location = /exact { # 精确匹配 /exact }

2. 前缀匹配(无修饰符)

不使用任何修饰符,按前缀匹配,匹配成功后继续搜索更精确的匹配。

nginx
location /prefix { # 匹配以 /prefix 开头的 URI }

3. 正则匹配(~ 和 ~*)

  • ~:区分大小写的正则匹配
  • ~*:不区分大小写的正则匹配
nginx
location ~ \.php$ { # 匹配以 .php 结尾的 URI(区分大小写) } location ~* \.(jpg|jpeg|png|gif)$ { # 匹配图片文件(不区分大小写) }

4. 前缀匹配(^~)

使用 ^~ 进行前缀匹配,如果匹配成功,立即停止搜索,不再检查正则表达式。

nginx
location ^~ /static/ { # 匹配以 /static/ 开头的 URI,不再检查正则 }

匹配优先级(从高到低):

  1. 精确匹配(=):优先级最高
  2. 前缀匹配(^~):如果匹配成功,停止搜索
  3. 正则匹配(~ 和 ~*):按配置顺序依次检查
  4. 前缀匹配(无修饰符):优先级最低

匹配示例:

nginx
server { listen 80; server_name example.com; # 1. 精确匹配 location = / { return 200 "Exact match /"; } # 2. ^~ 前缀匹配 location ^~ /images/ { return 200 "Prefix match ^~ /images/"; } # 3. 正则匹配(区分大小写) location ~ \.php$ { return 200 "Regex match .php"; } # 4. 正则匹配(不区分大小写) location ~* \.(jpg|jpeg|png|gif)$ { return 200 "Regex match images"; } # 5. 普通前缀匹配 location / { return 200 "Prefix match /"; } }

实际匹配结果:

  • 请求 / → 精确匹配 location = /
  • 请求 /images/logo.jpglocation ^~ /images/(停止搜索,不匹配正则)
  • 请求 /test.phplocation ~ \.php$
  • 请求 /photo.JPGlocation ~* \.(jpg|jpeg|png|gif)$(不区分大小写)
  • 请求 /otherlocation /

嵌套 Location:

nginx
location /api/ { # 外层 location proxy_pass http://backend; location /api/v1/ { # 内层 location,继承外层配置 proxy_pass http://backend_v1; } }

使用建议:

  1. 将精确匹配放在最前面
  2. 将正则匹配放在中间
  3. 将普通前缀匹配放在最后
  4. 使用 ^~ 避免不必要的正则匹配
  5. 合理使用正则匹配,避免过度使用影响性能

性能考虑:

  • 精确匹配和 ^~ 匹配性能最好
  • 正则匹配需要编译和执行,性能相对较低
  • 避免使用复杂的正则表达式
  • 正则匹配按配置顺序执行,将常用匹配放在前面

实际应用场景:

nginx
# 静态文件缓存 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; } # PHP 文件处理 location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; include fastcgi_params; } # API 请求代理 location /api/ { proxy_pass http://api_backend; } # 管理后台 location ^~ /admin/ { auth_basic "Restricted"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://admin_backend; }
标签:Nginx