FORMA

核心模块与常见指令详解

深入 Nginx 的指令层,是配置落地的关键。下面按功能模块拆解,每个指令都说明含义、语法、典型示例,并点出极易踩坑的地方。

一、核心功能模块

这些指令直接决定了 Nginx 的整体行为与性能。

指令上下文含义示例
usermainWorker 进程的运行用户,影响读写权限。建议用低权限用户(如 www-data)。user www-data;
worker_processesmainWorker 进程数,推荐 auto 自动匹配 CPU 核心数;也支持指定数字。worker_processes auto;
worker_connectionsevents每个 Worker 可同时打开的最大连接数。实际最大并发 = worker_processes * worker_connections (减去代理等占用)。需配合系统文件描述符限制 (ulimit -n)。events { worker_connections 2048; }
error_log多种错误日志路径与级别(debug, info, notice, warn, error, crit)。多上下文可用。error_log /var/log/nginx/error.log warn;
sendfilehttp, server, location开启零拷贝文件传输,直接在内核空间复制数据,大幅提升静态文件性能。sendfile on;
tcp_nopushhttp, server, locationsendfile on 时有效,将响应头和数据包合并发送,减少网络包数量,提高效率。tcp_nopush on;
keepalive_timeouthttp, server, location长连接超时时间。第一个参数是服务器端保持超时,第二个(可选)是设置响应头 Keep-Alive: timeout= 的值,告知客户端超时。keepalive_timeout 65 65;

优化建议sendfile on; tcp_nopush on; 搭配使用,对于静态文件服务极为有效。keepalive_timeout 不宜太长,避免闲置连接占用资源。

二、location 匹配规则(重中之重)

location 决定了请求最终由哪个块处理,规则精微,必须牢记优先级。

1. 匹配语法

匹配符示例含义
== /admin精确匹配,路径必须完全相等。优先级最高。
^~^~ /images/前缀优先,匹配前缀后不再检查正则表达式。
~~ \.php$正则匹配,区分大小写。
~*~* \.jpg$正则匹配,不区分大小写。
(无符号) //static普通前缀匹配,匹配路径的前缀部分。

2. 优先级顺序(非常重要)

Nginx 会按照以下顺序选择最终的 location

  1. 先遍历所有精确匹配 =,命中后立即停止,直接使用。
  2. 再遍历所有前缀匹配(含 ^~ 和普通前缀),找到最长命中。
    • 如果这个最长前缀带 ^~ 修饰符,则立即使用,不再检查正则
  3. 按配置文件中出现的顺序依次检查正则表达式(~~*),第一个匹配的正则被使用
  4. 若没有正则匹配,则使用第2步找到的最长前缀匹配。

流程图简示

text
请求进入 ─→ 是否有精确匹配(=)? ──YES→ 使用该 location
               │NO
               ▼
         找出最长前缀匹配(包括^~及无符号)
               │
         是否带 ^~ 修饰? ──YES→ 使用该 location(忽略正则)
               │NO
               ▼
         按出现顺序匹配正则(~ 和 ~*)
               │
         有命中? ──YES→ 使用第一个命中的正则 location
               │NO
               ▼
         使用之前找到的最长前缀匹配(无^~)

经典例子

nginx
location = /              { return 200 "exact /"; }
location /                { return 200 "prefix /"; }
location /documents/      { return 200 "prefix /documents/"; }
location ^~ /images/      { return 200 "prefix ^~ images"; }
location ~ \.(gif|jpg)$   { return 200 "regex images"; }
  • 请求 / :命中精确 =
  • 请求 /index.html :最长前缀是 /,然后正则都不匹配,最终使用 /
  • 请求 /images/logo.jpg :最长前缀是 ^~ /images/,因为有 ^~ 直接使用,不会尝试正则。
  • 请求 /documents/report.pdf :最长前缀 /documents/,无 ^~,接着检查正则,不匹配,使用 /documents/
  • 请求 /photo.jpg :最长前缀是 /,继续检查正则,匹配 ~ \.(gif|jpg)$,使用该正则 location。

三、静态资源服务

处理静态文件是 Nginx 的拿手好戏,但有几个易混淆点必须厘清。

1. rootalias 的区别(极易混淆)

  • root:将请求 URI 附加在指定的文件系统路径之后。
  • alias:将匹配到的路径替换为指定路径,URI 尾部不会追加。
指令配置示例请求 URI实际查找的文件路径
rootlocation /images/ { root /data; }/images/cat.png/data/images/cat.png
aliaslocation /images/ { alias /data; }/images/cat.png/data/cat.png

关键点alias 后面的路径直接对应匹配的 location 部分,末尾的 / 必须一致。若 location 后带有斜杠,alias 后面也建议带斜杠,否则可能出现路径拼接错误。alias 也可用于非前缀匹配,但最常用于替换路径。

2. indexautoindextry_files

  • index:定义默认查找的首页文件,按顺序尝试。
    nginx
    index index.html index.htm;
    

    当请求目录时(如 /),会依次查找这些文件,返回第一个存在的。
  • autoindex:开启目录列表,当没有 index 文件时显示文件清单。
    nginx
    autoindex on;   # 开启
    autoindex_exact_size off;  # 显示更易读的文件大小
    autoindex_localtime on;    # 显示本地时间
    
  • try_files:按顺序检查文件是否存在,以便实现前端路由、回退等功能。
    nginx
    location / {
        try_files $uri $uri/ /index.html;
    }
    

    工作流程:尝试 $uri 对应的文件,不存在则尝试 $uri/ 目录,都失败则内部重定向到 /index.html。常用于 SPA 应用。

3. expires 缓存设置

控制 ExpiresCache-Control 头,让浏览器或 CDN 缓存静态资源。

nginx
location ~* \.(jpg|jpeg|png|gif|css|js|ico|svg|woff2)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}
  • expires 30d; 表示 30 天后过期。
  • 也可用 expires -1; 表示禁止缓存,expires epoch; 强制使用 1970 时间点使缓存过期。

四、反向代理模块

Nginx 作为反向代理时,核心是 proxy_pass 及相关指令。

1. proxy_pass 后的 URI 有无斜杠的区别(重点)

这是配置反向代理时最经典的陷阱。proxy_pass 后是否带路径,直接影响请求 URI 如何传给后端。

  • 如果 proxy_pass 后没有 URI 或特别指定替换规则:会将完整的原始请求 URI 追加到指定地址。
  • 如果 proxy_pass 后带了 URI(哪怕是单纯的一个 /),Nginx 会将 location 匹配的部分替换为该 URI。

假设请求为 http://example.com/api/users?id=1

配置传递给后端的 URI说明
location /api { proxy_pass http://backend; }/api/users?id=1proxy_pass 无URI,完整转发
location /api { proxy_pass http://backend/; }//users?id=1匹配 /api(无斜杠),剩余部分带前导斜杠 /users,与 / 拼接成双斜杠,是经典踩坑点
location /api/ { proxy_pass http://backend/; }/users?id=1匹配 /api/(带斜杠),剩余部分 users 无前导斜杠,与 / 拼接后结果正常
location /api { proxy_pass http://backend/app; }/app/users?id=1替换 /api/app
location = /api/test { proxy_pass http://backend/test; }/test精确匹配,完全替换

核心口诀proxy_pass 后面不含路径则原样透传含路径则替换 location 匹配部分。强烈建议保持 location 后的路径与 proxy_pass 后路径的斜杠对应(同带或同不带),否则容易出现双斜杠或缺斜杠的意外结果。

2. proxy_set_header 透传真实 IP、Host 等

后端服务器通常需要客户端的真实信息,必须显式设置头信息。

nginx
location / {
    proxy_set_header Host $host;                              # 传递域名
    proxy_set_header X-Real-IP $remote_addr;                  # 客户端真实IP
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 代理链路
    proxy_set_header X-Forwarded-Proto $scheme;               # 原始协议
    proxy_set_header X-Forwarded-Host $host;
    proxy_pass http://backend;
}

注意:默认 Nginx 可能会透传 Host,但很多场景需要显式指定避免后端拿到错误的 Host。如果后端需要获取客户端 IP,需配置 --with-http_realip_module 且后端信任 Nginx 传递的 X-Forwarded-For

3. 超时设置

指令含义示例
proxy_connect_timeout与后端建立连接的超时(握手时间)proxy_connect_timeout 10s;
proxy_read_timeout等待后端响应的超时(两次读之间间隔)proxy_read_timeout 60s;
proxy_send_timeout向后端发送请求的超时proxy_send_timeout 60s;
proxy_buffering开启或关闭代理缓冲proxy_buffering on;

合理设置超时可避免慢后端拖垮 Nginx,同时配合 proxy_next_upstream 错误处理。

五、负载均衡

利用 upstream 块定义后端服务器组,并通过多种策略分发流量。

1. upstream 块定义

nginx
upstream backend {
    server 10.0.0.1:80 weight=3;
    server 10.0.0.2:80;
    server 10.0.0.3:80 backup;
}

然后在 location 中使用:

nginx
location / {
    proxy_pass http://backend;
}

2. 调度策略(NGINX Plus 拥有更多高级策略,以下为社区版):

  • 轮询(默认):请求按顺序逐一分配。
  • weight:加权轮询,性能高的机器分配更多请求。
    nginx
    server backend1.example.com weight=5;
    server backend2.example.com weight=1;
    
  • ip_hash:根据客户端 IP 哈希来固定后端,解决 Session 保持问题。
    nginx
    upstream backend {
        ip_hash;
        server ...
    }
    
  • least_conn:把请求发给当前活跃连接数最少的服务器,适合长连接场景。
    nginx
    upstream backend {
        least_conn;
        server ...
    }
    
  • fair(第三方):按后端响应时间来分配,需安装 nginx-upstream-fair 模块。
  • random(1.15.1+):随机选择,可加 two 参数随机选两个再从中挑最少连接,用于分布式环境。

3. 后端健康检查

  • 被动检查:Nginx 自动进行。当请求失败(连接超时、错误码等),会标记该服务器为 down 一段时间,通过 max_failsfail_timeout 控制。
    nginx
    server 10.0.0.1 max_fails=3 fail_timeout=30s;
    
    意味着 30 秒内失败 3 次就会暂停使用 30 秒。
  • 主动健康检查:社区版不自带,需通过第三方模块(如 nginx_upstream_check_module)或 Nginx Plus 实现,可定期探测后端 /health 端点。

六、Rewrite 与重定向

控制 URL 的重写与跳转,配合变量实现灵活规则。

1. return 指令

最简单直接的重定向,用于停止处理并返回状态码。

nginx
# 域名重定向
server {
    listen 80;
    server_name old.com;
    return 301 http://new.com$request_uri;
}
# HTTP 跳转 HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

优点:执行效率极高,比 if 安全,能快速终止请求。

2. rewrite 指令

rewrite regex replacement [flag];
用于内部重写或条件重定向,有四种 flag:

  • last:停止当前 rewrite 指令,用新的 URI 重新开始 location 匹配(类似内部转发)。
  • break:停止 rewrite,不再继续匹配 location,直接使用当前上下文处理。
  • redirect:返回 302 临时重定向。
  • permanent:返回 301 永久重定向。

常见场景

  • 伪静态rewrite ^/article-(\d+)\.html$ /article.php?id=$1 last;
  • 强制 HTTPS:结合 if,但建议优先使用 return
  • 路径清理:去掉重复斜杠等。

3. if 的谨慎使用

if 指令容易产生非预期行为,因为它不按标准的 rewrite 流程工作。常见的坑:

  • if 中包含 proxy_pass 可能导致未预期的变量错误。
  • 尽量避免在 location 内用 if 进行复杂的逻辑,优先使用 try_filesmap

若必须使用 if,最好仅限于 returnrewrite 操作。例如:

nginx
if ($http_user_agent ~* "bot") {
    return 403;
}

七、HTTPS 配置

现代化 Web 标配,Nginx 能高效终结 SSL/TLS。

1. 基础证书配置

nginx
server {
    listen 443 ssl;
    http2 on;                                              # nginx 1.25.1+ 用独立的 http2 指令
    server_name example.com;

    ssl_certificate     /etc/nginx/ssl/example.com.crt;    # 证书文件(含中间证书)
    ssl_certificate_key /etc/nginx/ssl/example.com.key;    # 私钥文件

    # 会话缓存提升 TLS 握手性能
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;
}

版本注意:nginx 1.25.1 起,listen 指令的 http2 参数已废弃,改用独立的 http2 on; 指令(同一 server 块内,listen 只负责端口与 ssl)。1.25.0 及更早版本仍需用 listen 443 ssl http2; 这种旧写法。

2. 协议与算法优化

nginx
ssl_protocols TLSv1.2 TLSv1.3;          # 仅启用安全协议
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;    # 高强度加密套件
ssl_prefer_server_ciphers on;           # 优先使用服务器端加密套件

# OCSP Stapling:减少客户端验证证书的延迟
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
  • ssl_ciphers 需根据安全标准定期更新,例如禁止 RC4。
  • OCSP Stapling:服务器在握手中附带 OCSP 响应,客户端无需单独查询,加快建立连接。

3. HTTP/2 开启与优势

nginx 1.25.1+ 用独立的 http2 on; 指令(旧版本用 listenhttp2 参数,见上文版本注意):

nginx
listen 443 ssl;
http2 on;

优势:基于二进制分帧,支持多路复用(同一连接上并行请求)、头部压缩 HPACK,显著减少延迟,提升页面加载速度。但 HTTP/2 必须配合 HTTPS,因此证书配置是前提。

注意:HTTP/2 服务器推送(Server Push)已在 nginx 1.25.1 中移除http2_push 指令不再可用),该特性因浏览器普遍不支持及实际收益有限已被业界弃用,如需类似效果可考虑 Link: <...>; rel=preload 响应头或 HTTP/3。

全站 HTTPS + HTTP/2 典型配置框架

nginx
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl;
    http2 on;
    server_name example.com;
    # 证书与安全配置...
    # 业务 location 配置...
}

掌握这些核心模块与指令,你就拥有了解决绝大多数 Nginx 场景的弹药库。不管是静态加速、反向代理、负载均衡还是 HTTPS 配置,都能得心应手。建议在测试环境中实际演练每个指令,尤其是 location 优先级和 proxy_pass 的 URI 处理,亲自看日志验证行为,印象会更加深刻。

参考文献

资料说明
nginx 文档官方
运维导读学习路径