Nginx Location 块详解:Web 流量路由

Nginx location 块是高效 Web 流量路由的支柱。本综合指南将分解五种不同的匹配修饰符(前缀、精确、最长前缀、正则表达式),并解释 Nginx 遵循的严格处理顺序。了解如何使用实用的配置示例准确路由静态资产、代理 API 调用和实施安全规则。掌握 location 块是精确控制流量的关键,可确保快速的服务器性能和稳健的配置管理。

66 浏览量

Nginx Location 块详解:路由 Web 流量

Nginx 以其作为 Web 服务器、反向代理和负载均衡器的速度和灵活性而闻名。实现对请求处理的精确控制的核心机制是 location 块。掌握 location 块对于任何希望优化性能、管理各种应用端点并保护特定资源的管理员来说都至关重要。

本指南全面介绍了 Nginx location 块,解释了不同的匹配修饰符、关键的处理顺序,并提供了有效路由 Web 流量的实用示例。

Location 块的作用和结构

一个 location 块定义了 Nginx 应如何根据请求 URI(统一资源标识符)来响应请求。这些块始终嵌套在 server 块内。

当客户端发起请求(例如,GET /images/logo.png)时,Nginx 会将请求 URI 与监听 server 块中所有定义的 location 块进行比对,以确定适当的处理方式,例如提供文件、重定向客户端或将请求代理到应用服务器。

基本语法

该语法要求一个修饰符(或无修饰符),后跟一个模式(URI):

location [modifier] [pattern] {
    # 配置指令 (例如, root, index, proxy_pass)
}

理解 Location 匹配类型(修饰符)

Nginx 提供了五种定义模式匹配的主要方式。修饰符的选择会极大地影响性能和路由精度。

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

这是默认的匹配类型。Nginx 搜索匹配请求 URI 的最长起始字符串。

修饰符 示例 行为 最佳使用场景
(无) location /blog/ 匹配以 /blog/ 开头的 URI (例如, /blog/post/1)。 通用目的,定义网站的大部分区域。

示例:

location /docs/ {
    root /var/www/html/public;
    # 如果 URI 是 /docs/manual.pdf, Nginx 将查找 /var/www/html/public/docs/manual.pdf
}

2. 精确匹配 (=)

此修饰符强制 URI 与模式之间进行精确匹配。如果匹配成功,Nginx 会立即停止搜索其他 location。这是最快的匹配类型。

修饰符 示例 行为 最佳使用场景
= location = /favicon.ico 仅精确匹配 URI /favicon.ico 处理特定的、频繁请求的文件或默认页面。

3. 最长前缀,非正则 (^~)

这是一种特殊的前缀匹配。如果 Nginx 使用 ^~ 找到了最长的前缀匹配,它将 立即停止 检查任何正则表达式 (regex) location 块,从而有效地覆盖它们。

修饰符 示例 行为 最佳使用场景
^~ location ^~ /assets/ 匹配以 /assets/ 开头的 URI,并阻止检查较慢的正则匹配。 快速提供静态资源,确保资源目录被可预测地处理。

4. 区分大小写的正则表达式 (~)

这使用 Perl 兼容正则表达式 (PCRE) 进行匹配。它功能强大,但比前缀匹配慢。第一个匹配的正则块获胜。

修饰符 示例 行为 最佳使用场景
~ location ~ \.php$ 匹配任何以 .php 结尾的 URI。 特定文件类型处理 (例如, 将 PHP 脚本传递给 PHP-FPM)。

5. 不区分大小写的正则表达式 (~*)

~ 相同,但匹配忽略 URI 的大小写。

修饰符 示例 行为 最佳使用场景
~* location ~* \.(jpg|gif|png)$ 匹配图像文件扩展名,无论大小写如何 (例如, .JPG.png)。 处理大小写一致性可能存在问题的文件。

关键的 Location 处理顺序

理解 Nginx 处理 location 块的顺序对于避免意外行为至关重要。Nginx 不会 简单地从上到下读取配置文件。它使用严格的层次结构:

  1. 精确匹配 (=): Nginx 首先检查所有精确匹配块。如果找到匹配项,处理立即停止,请求由该块处理。
  2. 最长前缀匹配覆盖 (^~): Nginx 接着搜索所有使用 ^~ 定义的 location 块。如果找到了最长匹配,处理立即停止。
  3. 正则表达式 (~~*): 如果请求未被 =^~ 处理,Nginx 会按它们在配置文件中出现的顺序检查所有正则 location(~~*)。第一个 匹配的块将被使用,并且处理停止。
  4. 最长标准前缀匹配(无修饰符): 如果未找到正则匹配,Nginx 最终使用最长匹配的标准前缀 location(即没有修饰符的那些)。
  5. 兜底匹配 (location /): 如果没有其他块匹配,则使用根 location (/) 作为回退处理器。

提示: 如果您有一个比标准前缀匹配更长的 ^~ 匹配,那么 ^~ 将始终获胜,并阻止检查正则块,即使某个正则块可以匹配该 URI。

实用配置场景

1. 优先处理静态资源以提高性能

为了确保 Nginx 直接快速地提供静态文件,防止较慢的正则检查和应用服务器进行不必要的处理,请使用 ^~ 修饰符。

server {
    listen 80;
    server_name myapp.com;

    # 1. 主页的精确匹配(最高优先级)
    location = / {
        proxy_pass http://backend_app_server;
    }

    # 2. 静态资源的快速处理,绕过正则检查
    location ^~ /static/ {
        root /var/www/site;
        expires 30d;
        break;
    }

    # 3. 常见媒体文件的正则表达式
    location ~* \.(gif|ico|css|js)$ {
        root /var/www/site;
        expires 7d;
    }

    # 4. 所有其他动态请求的回退
    location / {
        proxy_pass http://backend_app_server;
    }
}

2. 路由和代理 API 流量

当 Nginx 用作反向代理时,location 块对于将流量导向正确的上游应用服务器至关重要。

location /api/v1/ {
    # 确保 Nginx 尊重客户端连接设置
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;

    # 将所有以 /api/v1/ 开头的流量路由到后端服务
    proxy_pass http://api_backend_service/v1/;

    # 如果需要在将其传递给上游之前从 URI 中去除 /api/v1/,
    # 您可以使用正则匹配和重写:
    # location ~ ^/api/v1/(.*)$ {
    #     proxy_pass http://api_backend_service/$1;
    # }
}

3. 保护敏感目录

Location 块可用于拒绝外部访问敏感的内部目录,例如配置文件或隐藏目录(如 .git)。

# 拒绝访问以点开头的文件(隐藏文件)
location ~ /\.(ht|svn|git) {
    deny all;
    return 404; # 返回 404 而不是 403,以避免泄露它们的存在
}

# 拒绝访问特定的配置目录
location /app/config/ {
    deny all;
}

安全警告:使用 aliasroot

在 location 块内配置文件路径时,请注意 rootalias 之间的区别。

  • root: 将完整的请求 URI 附加到定义的路径。 (例如,location /images/ + root /data/ 导致路径为 /data/images/filename.jpg)
  • alias: 用定义的路径替换 URI 中匹配的部分。当 location 块使用正则表达式或需要在提供文件之前剥离部分路径时,这通常是必需的。 (例如,location /static/ + alias /opt/app/files/ 导致路径为 /opt/app/files/filename.jpg)

4. 处理末尾斜杠和重定向

通常需要强制执行一致的 URL 结构,例如确保目录始终以末尾斜杠 (/) 结束。

# 如果缺少,则强制为目录路径添加末尾斜杠
location ~* /[a-z0-9\-_]+$ {
    # 如果 URI 匹配文件,Nginx 将尝试提供该文件。否则,将其视为目录。
    # 检查请求的 URI 是否映射到磁盘上的目录:
    if (-d $request_filename) {
        return 301 $uri/;
    }
}

结论

Nginx location 块是服务器配置的支柱,对每个传入请求提供了细粒度的控制。通过理解五个匹配修饰符(=^~~~* 和前缀)以及严格的处理顺序,管理员可以创建高度优化、高效且可靠的路由配置。务必彻底测试更改,尤其是在混合使用前缀和正则表达式匹配时,以确保流量完全按预期流动。