Nginx简介

Nginx(发音同 engine x)是一款基于异步框架的轻量级/高性能的Web 服务器/反向代理服务器/缓存服务器/电

子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。由俄罗斯的程序设计师Igor Sysoev(伊戈尔·赛

索耶夫)所开发,最初供俄国大型网站Rambler.ru及搜寻引擎Rambler使用。

Nginx特点

  • 优点:
  1. 高并发量:基于 epoll/kqueue 模型开发,支持高并发量,官方说其支持高达 5w 并发连接数的响应

  2. 内存消耗少:善于处理静态文件,相较于其他web(比如:apache),占用更少的内存及资源

  3. 简单稳定:配置简单(一个conf文件),运行简单(nginx命令),而且运行稳定

  4. 模块化程度高:功能模块插件化设计,可以自由配置相应的功能。

  5. 支持Rwrite重写规则:能够根据域名、URL等请求关键点,实现定制化的高质量分发。

  6. 低成本:Nginx的负载均衡功能很强大而且免费开源,相较于几十万的硬件负载均衡器成本相当低。

  7. 支持多系统:Nginx代码完全用C语言从头写成,可以在各系统上编译并使用。

  • 缺点:

动态处理差:nginx善于处理静态文件,但是处理动态页面相较于Apache之类重量级的web软件能力稍欠缺。

rewrite弱:虽然nginx支持rewrite功能多,但是相较于Apache之类重量级的web软件能力稍欠缺。

安装

CentOS

# 1. 尝试直接使用 yum 安装
yum install nginx -y

# 2. 如果上面失败,可能需要先安装 EPEL 源 (CentOS 7 常用)
yum install epel-release -y
yum install nginx -y

[root@sovzn ~]# nginx -v
nginx version: nginx/1.20.1

[root@sovzn ~]# #  验证状态
[root@sovzn ~]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
   
   
[root@sovzn ~]# # 启动
[root@sovzn ~]# sudo systemctl start nginx
[root@sovzn ~]# systemctl status nginx

[root@sovzn ~]# # 设置开机自启
[root@sovzn ~]# sudo systemctl enable nginx
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
[root@sovzn ~]# 

[root@sovzn ~]# 检查配置文件
[root@sovzn ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@sovzn ~]# 

核心操作命令

操作 命令 说明
启动 systemctl start nginx 启动 Nginx 服务。如果未运行,则立即运行。
停止 systemctl stop nginx 停止 Nginx 服务。会中断当前正在处理的连接。
重启 systemctl restart nginx 先停止再启动。会中断连接,通常用于重大配置变更或升级。
重载 systemctl reload nginx 推荐用于修改配置后。重新加载配置文件,不中断现有连接(平滑过渡)。
查看状态 systemctl status nginx 查看服务是否运行、进程号、日志片段等。
开机自启 systemctl enable nginx 设置服务器重启后自动启动 Nginx。
禁止自启 systemctl disable nginx 取消开机自动启动。

工作目录

目录用途 包管理器安装 (yum/dnf/apt) (CentOS/Ubuntu/Debian) 源码编译安装 (默认) (make install) 说明
主配置文件 /etc/nginx/nginx.conf /usr/local/nginx/conf/nginx.conf 核心配置入口
额外配置目录 /etc/nginx/conf.d/ /usr/local/nginx/conf/conf.d/ (需手动创建) 存放 server 块配置,方便管理
网站根目录 /usr/share/nginx/html /usr/local/nginx/html 放置 index.html 等静态文件的地方
日志目录 /var/log/nginx/ /usr/local/nginx/logs/ 存放 access.logerror.log
进程 PID 文件 /run/nginx.pid/var/run/nginx.pid /usr/local/nginx/logs/nginx.pid 记录主进程 ID
临时文件目录 /var/cache/nginx/ /var/lib/nginx/ /usr/local/nginx/client_body_temp/ /usr/local/nginx/proxy_temp/ 缓存、请求体临时存储
可执行文件 /usr/sbin/nginx /usr/local/nginx/sbin/nginx 启动命令所在

如何准确查看当前的目录:

# 小写v只看版本信息,大写V可查看所有配置信息
nginx -V 

nginx version: nginx/1.24.0
built by gcc ...
configure arguments: 
  --prefix=/usr/local/nginx         <-- 这是您的【安装根目录】
  --conf-path=/etc/nginx/nginx.conf <-- 这是【配置文件】路径
  --http-log-path=/var/log/nginx/access.log <-- 【日志】路径
  --pid-path=/var/run/nginx.pid     <-- 【PID】路径
  ...

/etc/nginx/conf.d

/etc/nginx/conf.d 是 Nginx 的 子配置文件目录

它的主要作用是:模块化管理网站配置,让你不需要把所有网站的配置都写在一个巨大的主文件里。

它的工作原理:

  1. 主配置文件 (/etc/nginx/nginx.conf) 中通常包含这样一行代码:

    1include /etc/nginx/conf.d/*.conf;

    这行代码的意思是:“把 /etc/nginx/conf.d/ 目录下所有以 .conf 结尾的文件,都加载进来作为配置的一部分。”

  2. 启动时加载顺序

    • Nginx 启动时,先读 /etc/nginx/nginx.conf(全局配置,如用户、进程数、日志路径等)。
    • 读到 include 指令时,它会按字母顺序读取 conf.d 下的所有 .conf 文件。
    • 这些文件里的内容(通常是 server { ... } 块)会被合并到主配置中生效。

为什么要用它?

多网站管理:如果你在一台服务器上跑了 3 个网站(比如 a.com, b.com, c.com),你可以在 conf.d 下分别创建:

  • a.com.conf
server {
    listen 80;
    server_name www.a.com;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
  • b.com.conf
server {
    listen 80;
    server_name www.b.com;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
  • c.com.conf
server {
    listen 80;
    server_name www.c.com;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
  • 好处:修改 a.com 的配置时,不会误删 b.com 的代码;删除某个网站时,直接删掉对应的文件即可,非常干净。

配置文件详解

核心结构概览

Nginx 配置文件采用 模块化块状结构,主要由以下四个部分组成,层级关系如下:

# 1. 全局块 (Main Context)
#    影响 Nginx 整体运行的配置(用户、进程数、日志路径等)

# 2. Events 块 (Events Context)
#    配置网络连接处理模式(最大连接数、事件驱动模型)

# 3. HTTP 块 (HTTP Context)
#    配置 HTTP 服务器相关特性(反向代理、缓存、负载均衡、虚拟主机等)
#    ├── HTTP 全局配置 (Gzip, Log format, Include mime.types)
#    ├── Server 块 1 (虚拟主机 A: www.example.com)
#    │   └── Location 块 (路由规则)
#    ├── Server 块 2 (虚拟主机 B: api.example.com)
#    └── Upstream 块 (负载均衡服务器组)

全局块 (Main Context)

位置:文件最顶部,events 块之前。

作用:配置运行用户、工作进程数、日志路径、PID 文件等。

# 运行 Nginx 的用户和用户组 语法: user <username> <groupname>;
# (安全建议:使用专用用户如 nginx 或 www-data)
user nginx nginx;

# 如果没有 Nginx会自建用户和组
[root@sovzn html]# id nginx
uid=997(nginx) gid=993(nginx) groups=993(nginx)
[root@sovzn html]# 


# 工作进程数 (建议设置为等于 CPU 核心数,或设为 auto 自动检测)
worker_processes auto;

# 全局错误日志路径及级别 (级别: debug, info, notice, warn, error, crit)
error_log /var/log/nginx/error.log warn;

# PID 文件存放路径 (记录主进程 ID)
pid /var/run/nginx.pid;

# 限制打开文件描述符数量 (需配合系统 ulimit 使用)
worker_rlimit_nofile 65535;

Events 块 (Events Context)

位置events { ... }

作用:配置网络连接处理模式,直接影响并发性能。

events {
    # 单个 worker 进程允许的最大连接数
    # 理论最大连接数 = worker_processes * worker_connections
    worker_connections 10240;

    # 事件驱动模型 (Linux 推荐 epoll, FreeBSD 推荐 kqueue)
    use epoll;

    # 允许多个工作进程同时接受新连接 (提高高并发下的吞吐量)
    multi_accept on;
}

HTTP 块 (HTTP Context)

位置http { ... }

作用:配置所有 HTTP 相关的功能,是配置最复杂的部分。

HTTP 全局配置
http {
    # 引入 MIME 类型配置文件 (决定不同后缀文件的 Content-Type)
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # --- 日志格式定义 ---
    # $remote_addr: 客户端 IP
    # $time_local: 访问时间
    # $request: 请求行
    # $status: 状态码
    # $body_bytes_sent: 发送字节数
    # $http_referer: 来源页
    # $http_user_agent: 用户代理
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    # 访问日志路径
    access_log /var/log/nginx/access.log main;

    # --- 性能优化参数 ---
    sendfile on;              # 开启高效文件传输模式 (零拷贝)
    tcp_nopush on;            # 防止网络阻塞,配合 sendfile 使用
    tcp_nodelay on;           # 禁止 Nagle 算法,降低延迟 (适合短连接)
    
    # 连接超时设置
    keepalive_timeout 65;     # 长连接超时时间
    client_header_timeout 10;
    client_body_timeout 10;
    
    # 上传文件大小限制
    client_max_body_size 100M;

    # 开启 Gzip 压缩 (节省带宽)
    gzip on;
    gzip_min_length 1k;       # 最小压缩文件大小
    gzip_types text/plain application/json application/javascript text/css application/xml;
    gzip_vary on;             # 添加 Vary: Accept-Encoding 头

    # --- 引入其他配置文件 (最佳实践:将站点配置拆分) ---
    include /etc/nginx/conf.d/*.conf;
}
Server 块 (虚拟主机)

位置:嵌套在 http 块内。

作用:定义一个具体的网站或域名服务。

server {
    # 监听端口 (可指定 IP,默认监听所有 IP)
    listen 80;
    # 监听 IPv6 (如需)
    # listen [::]:80;

    # 域名匹配 (支持多个域名,空格分隔,支持泛域名 *.example.com)
    server_name example.com www.example.com;

    # 网站根目录
    root /usr/share/nginx/html;
    
    # 默认首页文件
    index index.html index.htm;

    # --- 字符集 ---
    charset utf-8;

    # --- Location 路由规则 (核心) ---
    # 1. 精确匹配 (=)
    location = /favicon.ico {
        log_off on;
        expires 30d;
    }

    # 2. 前缀匹配 (无符号 或 ^~) - 最常用
    # 匹配所有以 / 开头的请求
    location / {
        # 在配置的根目录尝试查找文件,如果不存在则作为目录查找,再不存在则转发给 @fallback
        try_files $uri $uri/ @fallback;
    }

    # 3. 正则匹配 (~ 区分大小写, ~* 不区分)
    # 匹配图片资源,设置长期缓存
    location ~* \.(gif|jpg|jpeg|png|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # 4. 命名 Location (@name) - 用于内部重定向
    location @fallback {
        return 404;
        # 或者转发给后端:proxy_pass http://backend;
    }

    # --- 错误页面配置 ---
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

在 Nginx 配置中,rootalias 都用于将请求的 URL 路径映射到服务器上的文件系统路径,但它们的映射规则有本质区别。简单来说,**root 是路径拼接,而 alias 是路径替换**。

核心区别

  • root (路径拼接): 会将 location 匹配到的路径追加root 指令指定的目录后面。
  • alias (路径替换): 会用 alias 指令指定的目录替换location 匹配到的路径部分。

场景示例

假设服务器上存在以下两个目录:

  • /var/www/html
  • /var/www/images

使用 root:

location /static/ {
    root /var/www/html;
}

当用户请求 http://example.com/static/logo.png 时,Nginx 会去查找:
/var/www/html + /static/logo.png = /var/www/html/static/logo.png

使用 alias:

location /static/ {
    alias /var/www/images/;
}

当用户请求 http://example.com/static/logo.png 时,Nginx 会去查找:
/var/www/images/ + logo.png = /var/www/images/logo.png
注意,URL 中的 /static/ 部分被 alias 指定的路径完全替换了。

特性 root alias
作用方式 拼接请求路径 替换 location 前缀
最终路径 root路径 + location路径 + 剩余URI alias路径 + 剩余URI
常见用途 整个站点的根目录,或保持URL与目录结构一致 将特定URL路径映射到任意目录
作用域 http, server, location 仅限 location
末尾斜杠 不强制要求 强烈建议加上,否则易出错
Upstream 块 (负载均衡)

位置:通常嵌套在 http 块内,server 块外。

作用:定义后端服务器组。

upstream backend_servers {
    # 负载均衡策略 (默认是轮询 round_robin)
    
    # 1. 加权轮询 (权重越高,分配越多)
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 weight=1;

    # 2. ip_hash (根据客户端 IP 哈希,解决 Session 共享问题)
    # ip_hash; 

    # 3. 备用服务器 (当其他服务器挂掉时启用)
    server 192.168.1.12:8080 backup;

    # 4. 失败判定 (可选)
    # max_fails=3 fail_timeout=30s;
}

# 在 Server 块中使用
server {
    location /api/ {
        proxy_pass http://backend_servers;
        
        # 传递真实客户端 IP 给后端
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # 超时设置
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

常用场景配置

静态网站 + HTTPS 强制跳转

# HTTP 强制跳转 HTTPS
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

# HTTPS 配置
server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    
    # SSL 优化配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
    
    # 静态资源缓存
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

反向代理

代理到 Node.js/Java/Go 应用

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000; # 后端应用地址
        
        # 关键:传递真实信息
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket 支持 (如果需要)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

限制访问 (防爬虫/限流)

http {
    # 定义限流区域 (每秒允许 10 个请求)
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

    server {
        # 应用限流
        location /login {
            limit_req zone=mylimit burst=20 nodelay;
            proxy_pass http://backend;
        }

        # 禁止特定 User-Agent (简单爬虫屏蔽)
        if ($http_user_agent ~* (Scrapy|curl|wget)) {
            return 403;
        }
        
        # 禁止特定 IP
        deny 192.168.1.100;
        allow all;
    }
}

斜杠核心详解

Location与Proxy_pass斜杠核心详解

Location匹配核心规则

核心原则:最长前缀匹配

谁更精确、前缀更长,谁的优先级更高,不存在宽泛路径覆盖精准路径的情况,这是前后端分离配置(/对应前端、/api/对应后端)不冲突的根本原因。

  • location /通用匹配,匹配所有请求路径,优先级最低
  • location /api:前缀匹配,匹配所有以**/api**开头的路径(如/api/api//apiabc/api/user),范围宽泛,易误匹配
  • location /api/:精准前缀匹配,仅匹配以**/api/**开头的路径(如/api/user/api/admin/list),无多余匹配,是生产环境标准写法
匹配优先级对比(由高到低)

location /api/(精准)> location /api(宽泛)> location /(通用)

示例:请求/api/user,优先匹配/api/,完全不走/的前端配置,无覆盖冲突。

Proxy_pass斜杠核心规则

核心逻辑

请求先匹配到对应location后,再看proxy_pass末尾是否带路径/斜杠,分两种核心场景:

  • proxy_pass无后缀斜杠/路径:原样转发,不做任何路径替换
  • proxy_pass有后缀斜杠/路径:字符串替换,将请求中匹配到location的前缀部分,替换为proxy_pass后缀的路径

场景1:location /api + proxy_pass无后缀斜杠

location /api {
    # 仅域名+端口,无任何后缀路径
    proxy_pass http://localhost:8080;
}
  • 匹配规则:匹配所有/api开头的请求
  • 转发规则:原样拼接完整请求路径
  • 示例:请求/api/user → 后端接收http://localhost:8080/api/user

场景2:location /api + proxy_pass后缀带/(踩坑场景)

location /api {
    # 后缀带/
    proxy_pass http://localhost:8080/;
}
  • 匹配规则:匹配所有/api开头的请求
  • 转发规则:将/api替换为/纯字符串替换,不智能合并斜杠
  • 示例:请求/api/user → 替换后/ + /user = //user,后端路径报错(双斜杠bug)

场景3:location /api/ + proxy_pass无后缀斜杠(生产常用)

location /api/ {
    proxy_pass http://localhost:8080;
}
  • 匹配规则:仅匹配/api/开头的请求
  • 转发规则:原样转发完整路径
  • 示例:请求/api/user → 后端接收http://localhost:8080/api/user

场景4:location /api/ + proxy_pass后缀带/(生产最常用)

location /api/ {
    proxy_pass http://localhost:8080/;
}
  • 匹配规则:仅匹配/api/开头的请求
  • 转发规则:将/api/替换为/,切掉接口前缀
  • 示例:请求/api/user → 后端接收http://localhost:8080/user

proxy_pass后缀自定义路径(非仅/)

proxy_pass后缀可自定义任意路径(如/admin/user/manage/api),替换规则完全一致,是多服务代理的常用玩法:

location /api/ {
    # 后缀自定义为/admin/
    proxy_pass http://localhost:8080/admin/;
}
  • 示例:请求/api/user/list → 将/api/替换为/admin/ → 后端接收/admin/user/list

核心流程总结(一句话记牢)

  1. 先匹配:按最长前缀原则,确定请求走哪个location
  2. 再转发
    1. proxy_pass无后缀斜杠/路径:原模原样转发请求路径
    2. proxy_pass有后缀斜杠/路径:把匹配到的location前缀,替换成代理后缀的路径

生产环境避坑准则

  1. 接口代理禁止用location /api,必须用location /api/,避免误匹配和双斜杠bug
  2. 需保留接口前缀:proxy_pass不加后缀斜杠
  3. 需切掉接口前缀:proxy_pass加后缀斜杠
  4. 前后端分离标准配置(无冲突、无覆盖)
server {
    listen 80;
    server_name localhost;

    # 前端静态资源:通用匹配,优先级最低
    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ /index.html; # 解决前端路由刷新404
    }

    # 后端接口:精准匹配,优先级更高,无覆盖
    location /api/ {
        # 切掉/api/转发,根据后端需求选择加/或不加
        proxy_pass http://localhost:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Location核心匹配符号与优先级

Nginx 通过不同的修饰符来区分匹配模式,其优先级顺序如下:

优先级 符号/类型 含义 匹配逻辑
1 (最高) = 精确匹配 请求 URI 必须与路径完全一致(例如 location = / 仅匹配根路径)。
2 ^~ 优先前缀匹配 若路径匹配成功,立即停止搜索正则表达式,直接使用此配置。
3 ~ 正则匹配(区分大小写) 使用正则表达式匹配,且严格区分大小写(如 .jpg.JPG 不同)。
3 ~* 正则匹配(不区分大小写) 使用正则表达式匹配,忽略大小写。
4 (无修饰符) 标准前缀匹配 普通的路径前缀匹配(如 location /images)。如果有多个匹配,取最长的那个。
5 (最低) / 通用匹配 兜底规则,匹配所有请求。

匹配流程逻辑

Nginx 处理请求时并非按配置文件顺序执行,而是遵循以下逻辑:

  1. 精确匹配检查:首先检查 = 修饰符。如果命中,立即结束查找。
  2. 前缀匹配检查:
    • 检查所有前缀字符串(包括 ^~ 和普通前缀)。
    • 如果 ^~ 匹配成功,立即结束查找。
    • 如果没有 ^~,Nginx 会暂存最长的那个普通前缀匹配。
  3. 正则匹配检查:按配置文件中的顺序检查 ~~*。如果找到匹配项,使用正则配置;否则使用第 2 步暂存的最长前缀匹配。
  4. 兜底:如果以上都没命中,则使用 / 通用匹配。

示例

# 规则 A: 精确匹配根路径
location = / { 
    # 返回 "Rule A" 
}

# 规则 B: 精确匹配 /login
location = /login { 
    # 返回 "Rule B" 
}

# 规则 C: 优先前缀匹配 /static/
location ^~ /static/ { 
    # 返回 "Rule C" 
}

# 规则 D: 正则匹配,区分大小写 (gif, jpg, png, js, css)
location ~ \.(gif|jpg|png|js|css)$ { 
    # 返回 "Rule D" 
}

# 规则 E: 正则匹配,不区分大小写 (.png)
location ~* \.png$ { 
    # 返回 "Rule E" 
}

# 规则 F: 通用匹配 (兜底)
location / { 
    # 返回 "Rule F" 
}

案例 1:访问根路径
请求 URL:http://domain.com/
匹配结果:规则 A
分析:location = / 是精确匹配,优先级最高,完全吻合。

案例 2:访问登录页
请求 URL:http://domain.com/login
匹配结果:规则 B
分析:location = /login 精确匹配成功。

案例 3:访问静态资源目录
请求 URL:http://domain.com/static/css/style.css
匹配结果:规则 C
分析:
虽然 .css 后缀也能匹配规则 D,但 ^~ 修饰符的优先级(第 2 级)高于正则匹配(第 3 级)。
Nginx 发现 ^~ /static/ 匹配成功后,停止搜索正则,直接返回规则 C。

案例 4:访问普通图片(小写后缀)
请求 URL:http://domain.com/uploads/image.jpg
匹配结果:规则 D
分析:
没有精确匹配,也没有 ^~ 前缀匹配。
进入正则检查:规则 D ~ \.(jpg)$ 匹配成功。
注意:虽然规则 E 也能匹配 png,但这里是 jpg,且规则 D 在配置中通常先于 E 被扫描(或者即使顺序相反,jpg 也不符合 E 的 png 条件)。

案例 5:访问大写后缀图片(大小写敏感测试)
请求 URL:http://domain.com/uploads/image.JPG
匹配结果:规则 F
分析:
规则 D (~) 是区分大小写的,.JPG 不匹配 .jpg,所以规则 D 失败。
规则 E (~* .png$) 只匹配 png,所以失败。
最终落入通用匹配,命中规则 F。

案例 6:访问大写 PNG 图片(不区分大小写测试)
请求 URL:http://domain.com/uploads/image.PNG
匹配结果:规则 E
分析:
规则 D 失败(区分大小写,D 里没有 .PNG)。
规则 E (~* \.png$) 是不区分大小写的,成功匹配 .PNG。

案例 7:访问未知路径
请求 URL:http://domain.com/abc/test
匹配结果:规则 F
分析:
没有精确匹配。
没有前缀匹配。
没有正则匹配。
最终命中兜底的 location /

Location中的 try_files

核心定义

try_files 是 Nginx 中用于处理请求路由的核心指令,其核心思想是“按优先级尝试,优雅降级”

  • 功能:按顺序检查一个或多个文件、目录是否存在。
  • 行为:返回第一个找到的资源。
  • 兜底:如果所有资源都不存在,则执行最后一个参数指定的“回退”(fallback)操作。
try_files file1 file2 ... fallback;

完整配置示例

1    server {
2    listen 80;
3    server_name example.com;
4    
5    # 1. 指定物理根目录(地基)
6    root /var/www/myapp;
7    
8    # 2. 指定默认首页文件(配合目录匹配使用)
9    index index.html;
10    
11    location / {
12        # 3. 核心逻辑:按顺序检查
13        try_files $uri $uri/ /index.html;
14    }
15}

工作流程

  1. 检查第一个参数:Nginx 根据 root 拼接完整路径,检查文件是否存在。
  2. 命中即停:如果文件存在,立即返回,后续参数不再检查。
  3. 顺序检查:如果文件不存在,继续检查下一个参数。
  4. 执行回退:如果所有检查都失败,执行最后一个 fallback 参数。

经典应用场景

单页应用(SPA)路由支持

1    location / {
2    # 1. 尝试找文件 ($uri)
3    # 2. 尝试找目录 ($uri/)
4    # 3. 都找不到,返回 /index.html,交给前端路由处理  $uri表示按名称匹配文件,$uri/ 表示按名称匹配路径
5    try_files $uri $uri/ /index.html;
6}
  • **请求 /about**:服务器上无 /about 文件,也无 /about/ 目录,最终返回 /index.html,前端 JS 接管并渲染”关于”页面。

网站维护模式

1    location / {
2    # 1. 检查维护页面是否存在
3    # 2. 若不存在,再正常处理请求
4    # 3. 若请求也找不到,返回404
5    try_files /system/maintenance.html $uri $uri/ =404;
6}
  • 开启维护:只需将 maintenance.html 上传到 /system/ 目录,所有请求都会被拦截并返回维护页。
  • 关闭维护:删除该文件,网站即刻恢复正常。

静态资源与后端代理分离

1    location / {
2    # 1. 尝试找静态文件
3    # 2. 找不到,转发给 @backend 处理
4    try_files $uri $uri/ @backend;
5}
6
7    location @backend {
8    proxy_pass http://127.0.0.1:3000;
9}

重要注意事项

  • 查找范围try_files 只在 rootalias 指令指定的目录范围内查找文件,不会扫描整个服务器硬盘。
  • 顺序至关重要:Nginx 严格按照从左到右的顺序检查,找到即停。因此,优先级高的检查项必须放在前面。
  • fallback 是必选项:最后一个参数必须存在,否则配置会出错。
  • 性能影响:每个文件检查都会产生一次磁盘 I/O 操作。虽然很快,但在极高并发下,过多的检查项可能会带来轻微的性能损耗。
  • 内部重定向:当 fallback 是一个 URI 或命名 location 时,会发生内部重定向,这意味着 $uri 变量的值会改变,并进入新的 location 块进行处理。

Nginx 临时跳转(302)

核心定义

302 Found 是一种外部重定向,意为“资源暂时搬家了”。

  • 对用户:浏览器地址栏会变成新地址。
  • 对浏览器:这是一个临时指令。浏览器不会永久缓存这个跳转规则。下次访问旧地址时,浏览器依然会向服务器发起请求,询问“现在去哪?”。
  • 默认行为:在 Nginx 的 return 指令中,如果省略状态码,默认就是 302

实现方式

使用 return 指令(推荐)
这是最简单、性能最高的方法。

location /old-page {
   # 显式写法(推荐,清晰)
    return 302 https://www.example.com/new-page;
   
    # 简写写法(默认也是 302)
    # return https://www.example.com/new-page;
        
    # return  /error;
}

#location /error {     
#    return  400;
#}

使用 rewrite 指令
适合配合正则表达式进行复杂的路径匹配。

1   location /old-page {
2    # redirect 关键字等同于 302
3    rewrite ^/old-page$ https://www.example.com/new-page redirect;
4}

302 与 301 的终极对比

301 也能实现跳转功能,但是……浏览器会把它“写死”在缓存里。

代价是浏览器会认为这个变动是永久的,如果不清楚缓存,就算删除了跳转配置,访问旧地址时还会跳转到以前配置的新地址

特性 302 (临时跳转) 301 (永久跳转)
浏览器缓存 不缓存 (或缓存时间极短) 积极缓存 (会“写死”在浏览器里)
服务器交互 每次都会问服务器:“今天去哪?” 首次之后,浏览器自己跳,不问服务器
SEO 权重 不传递。搜索引擎保留原 URL 的权重 传递。搜索引擎将权重转移给新 URL
后悔成本 。服务器改配置,立马生效 。需用户手动清浏览器缓存才能取消

常见应用场景

  • 网站临时维护:将用户临时引导至“维护中”页面,维护结束后删除配置即可恢复。
  • A/B 测试:临时将部分流量跳转到新版本页面进行测试。
  • 兼容旧链接:旧 URL 失效时,临时指向新链接,避免 404 错误。
  • 登录后跳转:用户访问需登录页面时,临时跳转至登录页,登录成功后再跳回。

开发与调试建议

  • 黄金法则:开发和测试阶段,永远优先使用 302!
  • 原因:避免浏览器缓存 301 带来的麻烦,防止修改配置后浏览器依然“固执”地执行旧跳转。
  • 清除 301 缓存方法
    • 使用浏览器的无痕/隐私窗口访问。
    • 在开发者工具的 Network 面板中勾选 Disable cache
    • 手动清除浏览器“缓存的图片和文件”。

autoindex

  • 功能:当访问的目录中不存在默认首页文件(如 index.html)时,自动生成并显示该目录的文件列表页面。
  • 默认状态off (关闭),出于安全考虑,Nginx 默认不列出目录内容。
指令 默认值 作用 推荐配置
autoindex off 开启或关闭目录列表功能 on
autoindex_exact_size on 显示文件精确字节数 (on) 或人类可读格式 (KB/MB/GB) (off) off
autoindex_localtime off 显示文件时间为服务器本地时间 (on) 或 UTC 时间 (off) on
autoindex_format html 定义列表输出格式 (html, json, xml, jsonp) html

利用 autoindex 是搭建简易文件下载服务器(下载站点)最常用、最快捷的方法。

server {
    listen 80;
    server_name download.example.com;

    # 1. 定义文件存储的物理路径
    root /data/files; 

    location / {
        # --- 基础列表功能 ---
        autoindex on;              # 开启目录列表
        autoindex_exact_size off;  # 关闭精确字节,显示为 KB/MB/GB(更人性化)
        autoindex_localtime on;    # 显示服务器本地时间(而非 GMT 时间)

        # --- 解决中文乱码 ---
        # 如果文件名包含中文,浏览器可能会乱码,强制设置字符集
        charset utf-8,gbk;

        # --- 强制下载功能 (关键点) ---
        # 默认情况下,txt/pdf/jpg 会在浏览器打开。
        # 下面的配置强制特定后缀的文件弹出“下载”对话框
        if ($request_filename ~* ^.*?\.(txt|doc|pdf|zip|rar|jpg|png)$) {
            add_header Content-Disposition 'attachment;';
        }
    }
}