Nginx 配置详解

🔐 适用场景:Web服务器配置、反向代理、负载均衡、静态资源服务


📑 目录

  1. Nginx 基础架构
  2. 安装与启动
  3. 核心配置结构
  4. HTTP 服务器配置
  5. 反向代理配置
  6. 负载均衡
  7. HTTPS 配置
  8. 高级特性
  9. 性能优化
  10. 故障排查

1. Nginx 基础架构

1.1 什么是 Nginx

Nginx(发音为"engine-x")是一款开源的高性能HTTP服务器和反向代理服务器,由俄罗斯程序员Igor Sysoev于2004年首次发布。它以其高并发、低内存消耗和稳定性著称,目前已被全球约三分之一的网站采用。

┌─────────────────────────────────────────────────────────┐
│                     🟣 Nginx                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐      │
│  │   Master    │  │   Worker    │  │   Worker    │      │
│  │   Process   │──│   Process   │  │   Process   │      │
│  └─────────────┘  └─────────────┘  └─────────────┘      │
│        │                │                │              │
│  ┌─────┴────────────────┴────────────────┴─────┐        │
│  │              🔵 Connection Pool               │        │
│  └──────────────────────────────────────────────┘        │
└─────────────────────────────────────────────────────────┘

1.2 核心概念解释

概念 解释
Master Process(主进程) Nginx的启动进程,负责读取配置文件、管理Worker进程、接收信号、重载配置等管理工作。它不处理实际的用户请求,而是监控和管理Worker进程的状态。
Worker Process(工作进程) 实际处理用户请求的进程。Master进程会fork出多个Worker进程,每个Worker独立处理请求。Worker进程之间通过共享内存进行通信。
Connection Pool(连接池) Nginx使用连接池来管理客户端连接,避免频繁创建和销毁连接的开销。每个Worker进程有自己的连接池。
Event-Driven(事件驱动) Nginx采用事件驱动架构,使用epoll(Linux)、kqueue(FreeBSD/macOS)、select/poll等高效的事件通知机制,能够同时处理大量并发连接。
Non-blocking I/O(非阻塞I/O) Nginx使用非阻塞I/O操作,当等待I/O操作完成时,进程可以继续处理其他请求,从而最大化资源利用率。

1.3 架构特点详解

🎯 特性 📄 说明
🐧 多进程 Master-Worker模式:Master进程负责管理(读取配置、发出信号),Worker进程负责处理请求。Worker数量通常设置为CPU核心数,可通过worker_processes配置。
🔄 事件驱动 Nginx使用epoll(Linux 2.6+)、kqueue(BSD/macOS)、select/poll等高效事件模型,能够同时处理数十万个并发连接。
📦 模块化 Nginx采用模块化设计,核心模块提供基础功能,第三方模块(如SSL、压缩、重写等)可按需加载。
⚡ 高性能 得益于事件驱动和非阻塞I/O,Nginx能以少量进程处理大量并发请求,内存消耗极低。
🛡️ 热部署 可以在不中断服务的情况下重载配置、更换日志文件、更新Nginx本身(通过USR2信号)。

2. 安装与启动

2.1 什么是安装方式

安装方式 解释 适用场景
包管理器安装(apt/yum/brew) 通过操作系统自带的包管理器安装,是最简单的方式 快速部署、不需要特殊模块
源码编译安装 从官网下载源码,使用./configure配置后编译安装 需要定制化模块、生产环境追求最新版本
Docker 使用官方Docker镜像 开发环境、容器化部署

apt/yum/brew 的区别

  • apt:Debian/Ubuntu 系发行版的包管理器
  • yum:RHEL/CentOS 旧版本的包管理器
  • dnf:RHEL/CentOS 新版本的包管理器(yum的升级版)
  • brew:macOS 的包管理器

2.2 安装方式

# 🖥️ Ubuntu/Debian(使用apt包管理器)
sudo apt update && sudo apt install nginx

# 🖥️ CentOS/RHEL(使用dnf/yum包管理器)
sudo yum install nginx      # 旧版本
sudo dnf install nginx      # 新版本

# 🖥️ macOS(使用Homebrew包管理器)
brew install nginx

# 🖥️ 源码编译安装
# 1. 下载源码:https://nginx.org/en/download.html
# 2. 解压后进入目录
# 3. 配置编译选项
./configure --prefix=/usr/local/nginx --with-http_ssl_module
# 4. 编译并安装
make && make install

2.3 启动与管理命令详解

命令 解释 信号类型
systemctl start nginx 使用systemd服务管理器启动Nginx systemd是现代Linux的初始化系统
nginx 直接启动Nginx(不通过systemd) 适用于没有systemd的环境
systemctl stop nginx 强制停止Nginx服务 发送TERM信号
systemctl stop nginx 发送QUIT信号,优雅停止(等待现有请求处理完) QUIT信号的优雅停止
nginx -s reload 发送HUP信号,重新加载配置文件 不中断现有连接
nginx -t 测试配置文件语法是否正确 不实际重载
nginx -s stop 发送TERM信号,立即停止 强制停止
nginx -s quit 发送QUIT信号,优雅停止 等待请求处理完毕后停止
nginx -v 显示Nginx版本号 仅查看版本
nginx -V 显示Nginx版本、编译参数和配置参数 调试时使用

2.4 启动与管理命令

# 🔧 启动 Nginx
sudo systemctl start nginx    # systemd
sudo nginx                    # 直接启动

# 🔧 停止 Nginx
sudo systemctl stop nginx

# 🔧 重载配置(不断开连接)
sudo nginx -s reload

# 🔧 检查配置语法
sudo nginx -t

# 🔧 查看版本
nginx -v
┌─────────────────────────────────────────────────────┐
│              🔧 Nginx 进程管理流程                    │
│                                                     │
│  ┌──────────┐    reload     ┌──────────┐            │
│  │  Master  │──────────────│  Master  │            │
│  │  (old)   │              │  (new)   │            │
│  └────┬─────┘              └────┬─────┘            │
│       │                         │                   │
│       │   向旧workers发QUIT信号  │                   │
│       ▼                         ▼                   │
│  ┌──────────┐              ┌──────────┐            │
│  │  Worker  │      →       │  Worker  │            │
│  │  (old)   │   停止处理     │  (new)   │            │
│  └──────────┘              └──────────┘            │
│                                                     │
└─────────────────────────────────────────────────────┘

3. 核心配置结构

3.1 配置文件位置详解

🗂️📁 路径 📄 说明 备注
/etc/nginx/nginx.conf 主配置文件,Nginx启动时默认读取 所有配置文件的入口
/etc/nginx/conf.d/ 自定义配置目录,用于存放额外的server块配置 通常放server配置
/etc/nginx/sites-enabled/ 站点配置目录(Debian/Ubuntu特有) 通过符号链接启用站点
/usr/local/nginx/conf/ 源码编译安装的默认路径 编译安装时指定的prefix路径

为什么要有多个配置目录?

  • 模块化:不同站点/功能的配置分开管理
  • 便于维护:修改一个站点配置不影响其他站点
  • 避免冲突:多人协作时不易产生冲突

3.2 配置块层级概念

Nginx配置由多个配置块(Block)组成,形成层级结构:

配置块 名称 作用 包含的子块
main(全局块) 最外层配置 设置Nginx运行的整体参数 events块、http块
events块 事件块 配置连接处理方式
http块 HTTP块 HTTP服务器相关配置 server块、upstream块
server块 虚拟主机块 定义单个站点的配置 location块
location块 URL路由块 根据URL路径处理请求
upstream块 上游服务器块 定义后端服务器组(负载均衡)

3.3 配置指令层级图

┌─────────────────────────────────────────────────────┐
│           🟣 main context(全局块)                   │
│  ┌─────────────────────────────────────────────────┐│
│  │  user, worker_processes, error_log, pid        ││
│  └─────────────────────────────────────────────────┘│
│                      ▼                               │
│  ┌─────────────────────────────────────────────────┐│
│  │           🔵 events 块                          ││
│  │  ┌─────────────────────────────────────────────┐││
│  │  │  worker_connections, use, multi_accept    │││
│  │  └─────────────────────────────────────────────┘││
│  └─────────────────────────────────────────────────┘│
│                      ▼                               │
│  ┌─────────────────────────────────────────────────┐│
│  │           🟢 http 块                            ││
│  │  ┌─────────────────────────────────────────────┐││
│  │  │  include, log_format, access_log, gzip    │││
│  │  └─────────────────────────────────────────────┘││
│  │                      ▼                         ││
│  │  ┌─────────────────────────────────────────────┐││
│  │  │      🟢 server 块(虚拟主机)               │││
│  │  │  ┌───────────────────────────────────────┐  │││
│  │  │  │  listen, server_name, ssl_certificate│  │││
│  │  │  └───────────────────────────────────────┘  │││
│  │  │              ▼                             │││
│  │  │  ┌───────────────────────────────────────┐  │││
│  │  │  │     🟡 location 块(URL路由)          │  │││
│  │  │  │  root, index, proxy_pass, try_files  │  │││
│  │  │  └───────────────────────────────────────┘  │││
│  │  └─────────────────────────────────────────────┘││
│  └─────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────┘

3.4 配置文件检查详解

nginx -t 是部署前最重要的命令,用于验证配置文件的语法和逻辑正确性。

# 🔧 测试配置语法(最常用)
sudo nginx -t
# 输出:nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# 输出:nginx: configuration file /etc/nginx/nginx.conf test is successful

# 🔧 查看完整配置(含引入文件展开)- 用于调试include指令
sudo nginx -T

# 🔧 指定配置文件路径测试 - 用于测试非默认位置的配置文件
sudo nginx -t -c /path/to/nginx.conf
命令 解释 使用场景
nginx -t 测试配置文件语法和有效性 重载配置前必用
nginx -T 测试并打印完整配置(包括include的文件内容) 调试配置include问题
nginx -t -c path 测试指定路径的配置文件 测试备选配置文件

4. HTTP 服务器配置

4.1 基础虚拟主机详解

虚拟主机(Virtual Host) 是Nginx通过server块来区分不同网站(或域名的机制。Nginx通过请求的Host来识别应该哪个server块处理请求。

概念 解释
listen 监听端口,指定Nginx在这个端口上接受请求。80是HTTP标准端口,443是HTTPS标准端口
server_name 服务器域名,用于匹配请求头中的Host字段。可以是精确域名、通配符或正则表达式
root 文档根目录,定义网站文件存放的物理路径。请求的URI会追加到此目录下查找文件
index 默认首页文件,当请求目录而非文件时,Nginx会按顺序查找这些文件
access_log 访问日志路径,记录所有入站请求的信息
error_log 错误日志路径,记录服务器错误和警告
try_files 尝试查找文件的规则,按顺序检查文件/目录是否存在,不存在则回退到指定URI或返回错误码
expires 设置缓存过期时间,30d表示30天
add_header 向响应添加自定义HTTP头部
server {
    listen       80;              # 监听80端口(HTTP标准端口)
    server_name  example.com;     # 域名配置,支持精确匹配、通配符、正则

    # 文档根目录 - 网站文件存放的物理路径
    root  /var/www/example.com/html;

    # 默认首页 - 当请求目录时按顺序查找
    index index.html index.htm;

    # 访问日志 - 记录所有请求
    access_log /var/log/nginx/example.com.access.log;
    error_log  /var/log/nginx/example.com.error.log;

    # location 路由 - 根据URL路径处理请求
    location / {
        # try_files:依次尝试 $uri(文件)、$uri/(目录)、=404(返回404)
        try_files $uri $uri/ =404;
    }

    # 静态资源缓存 - /static/ 路径下的文件缓存30天
    location /static/ {
        expires 30d;                              # 缓存30天
        add_header Cache-Control "public, immutable";  # 公开缓存、不可变性
    }

    # 错误页面 - 自定义错误页面
    error_page 404 /404.html;                      # 404时显示/404.html
    error_page 500 502 503 504 /50x.html;         # 5xx服务器错误时显示/50x.html
}

4.2 server_name 多种配置详解

server_name指令用于匹配请求头中的Host字段,支持多种配置方式:

配置方式 示例 匹配规则
精确匹配 server_name example.com 仅匹配example.com
多个域名 server_name example.com www.example.com 匹配多个指定域名
通配符(首) server_name *.example.com 匹配任何子域名(如sub.example.com
通配符(尾) server_name example.* 匹配example开头的任何后缀(如example.comexample.org
正则表达式 server_name ~^www\d+\.example\.com$ 使用正则匹配(以~开头)
默认服务器 server_name _server_name "" 处理所有未匹配的请求
server {
    # 精确匹配
    server_name example.com;

    # 多个域名(按顺序匹配)
    server_name example.com www.example.com;

    # 通配符(只能在首尾)—— 匹配 sub.example.com
    server_name *.example.com;

    # 另一个通配符示例 —— 匹配 example.com example.org example.net
    server_name example.*;

    # 正则表达式(以 ~ 开头)—— 匹配 www1.example.com, www2.example.com
    server_name ~^www\d+\.example\.com$;

    # 默认服务器 —— 处理未匹配的所有请求(兜底)
    server_name _;  # 或使用空字符串 ""
}

4.3 location 匹配规则详解

location块用于根据请求的URI路径来定义如何处理请求。Nginx支持多种匹配类型:

语法 名称 说明
location /uri 前缀匹配 匹配以/uri开头的路径(最常用)
location / 根匹配 匹配所有路径
location = /exact 精确匹配 精确匹配URI,优先级最高
location ^~ /prefix 前缀匹配(禁用正则) 匹配前缀路径,并禁用该location后的正则匹配
location ~ /regex 正则匹配(区分大小写) 使用正则表达式匹配(区分大小写)
location ~* /regex 正则匹配(不区分大小写) 使用正则表达式匹配(不区分大小写)

4.4 location 优先级详解

Nginx按以下优先级顺序匹配location(从高到低):

┌─────────────────────────────────────────────────────────┐
│              🟡 Location 匹配优先级                       │
│                                                         │
│  🟣 1. = (精确匹配)                                       │
│     └─ location = /exact                                │
│     最高优先级,完全相等才匹配                              │
│                                                         │
│  🔵 2. ^~ (前缀匹配,禁用正则)                             │
│     └─ location ^~ /prefix                              │
│     匹配前缀路径,匹配后不再检查正则                        │
│                                                         │
│  🟢 3. ~ 或 ~* (正则匹配,按顺序匹配)                       │
│     └─ location ~ \.(jpg|png|gif)$                      │
│     按配置文件中的顺序匹配,第一个匹配的生效                 │
│                                                         │
│  🟡 4. 普通前缀匹配(最长前缀匹配)                          │
│     └─ location /path                                   │
│     └─ location /path/deeper                            │
│     匹配最长的前缀                                        │
│                                                         │
└─────────────────────────────────────────────────────────┘

优先级总结

  1. = 精确匹配 → 最高优先级
  2. ^~ 前缀匹配(禁用正则)→ 次高优先级
  3. ~~* 正则匹配 → 按书写顺序,第一个匹配的成功
  4. 普通前缀匹配 → 匹配最长前缀

4.5 完整配置示例详解

这是一个典型的Web应用配置,包含了静态资源、PHP处理、安全控制等常用配置:

server {
    listen 80;                              # 监听端口
    server_name www.example.com example.com; # 多个域名

    root /var/www/example.com;              # 文档根目录
    index index.html;                       # 默认首页

    # 根路径 —— try_files 依次尝试文件、目录,最后回退到 /index.html
    location / {
        try_files $uri $uri/ /index.html;
    }

    # PHP 处理(使用 php-fpm)—— 正则匹配 .php 结尾的请求
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php-fpm.sock;  # PHP-FPM Unix socket 路径
        fastcgi_index index.php;                   # 默认首页
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;  # 完整脚本路径
        include fastcgi_params;                     # 引入 fastcgi 参数
    }

    # 静态资源(带缓存)—— 不区分大小写正则匹配静态文件
    location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ {
        expires 1y;                    # 缓存1年
        access_log off;               # 关闭访问日志(减少IO)
        add_header Cache-Control "public, immutable";  # 公开缓存、不可变性
    }

    # 禁止访问隐藏文件 —— 正则匹配以 . 开头的路径
    location ~ /\. {
        deny all;                     # 拒绝所有访问
        access_log off;               # 关闭访问日志
        log_not_found off;            # 关闭"文件未找到"日志
    }

    # 禁止访问敏感路径 —— 匹配 .git、.env 等敏感目录
    location ~* /\.(git|env|htaccess|htpasswd) {
        deny all;
    }

    # 错误页面 —— 自定义错误页面
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
}

5. 反向代理配置

5.1 反向代理概念详解

反向代理(Reverse Proxy) 是指Nginx作为代理服务器,代替客户端向后端服务器发起请求,并将后端服务器的响应转发回客户端。与正向代理(代理客户端)相反,反向代理对客户端是透明的。

概念 正向代理 反向代理
代理对象 客户端(浏览器) 服务器(后端应用)
用途 FQ、缓存、访问控制 负载均衡、安全防护、缓存加速
客户端知道吗 知道(需配置代理) 不知道(像访问真实服务器)
代表软件 Squid Nginx、HAProxy
┌─────────────────────────────────────────────────────────┐
│           🔄 Nginx 反向代理请求流程                        │
│                                                         │
│   Client(不知道后端存在)                                 │
│     │                                                    │
│     │  ① 请求 www.example.com                           │
│     ▼                                                    │
│   ┌────────┐                                            │
│   │  🟣    │  Nginx (代理服务器)                         │
│   │ Nginx  │  客户端以为这是真实服务器                      │
│   └────┬───┘                                            │
│        │ ② 转发请求到后端服务器(对客户端透明)            │
│        ▼                                                │
│   ┌────────┐     ┌────────┐     ┌────────┐             │
│   │ 🔵     │     │ 🔵     │     │ 🔵     │             │
│   │Backend │     │Backend │     │Backend │             │
│   │ :3000  │     │ :3001  │     │ :3002  │             │
│   └────────┘     └────────┘     └────────┘             │
│        │ ③ 返回响应                                      │
│        ▼                                                │
│   Client ←── ④ 转发响应(看起来像Nginx返回的)             │
│                                                         │
└─────────────────────────────────────────────────────────┘

5.2 代理到后端服务器详解

proxy_pass是反向代理的核心指令,用于指定后端服务器的地址。

指令 说明
proxy_pass 反向代理目标地址,可以是http://、https://或unix:路径
proxy_set_header 设置转发给后端的请求头(非常重要!)
proxy_connect_timeout 与后端建立连接的超时时间
proxy_send_timeout 向后端发送请求的超时时间
proxy_read_timeout 等待后端响应的超时时间
proxy_buffering 是否启用缓冲区(开启可提高性能)
proxy_buffer_size 响应头缓冲区大小
proxy_buffers 响应体缓冲区数量和大小

重要Headers说明

Header 解释 为什么要传
Host $host 请求的域名 后端应用需要知道请求哪个虚拟主机
X-Real-IP $remote_addr 客户端真实IP 后端需要记录真实客户端IP
X-Forwarded-For 代理链IP列表 追踪请求经过的代理链
X-Forwarded-Proto 原始协议 后端知道是http还是https
server {
    listen 80;
    server_name www.example.com;

    # 代理到后端应用
    location / {
        proxy_pass http://127.0.0.1:3000;    # 后端服务器地址

        # 传递原始请求头(重要!否则后端无法获取真实信息)
        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;      # 原始协议

        # 超时配置(单位:s=秒,ms=毫秒)
        proxy_connect_timeout 60s;   # 连接后端超时
        proxy_send_timeout    60s;   # 发送数据超时
        proxy_read_timeout    60s;   # 读取响应超时

        # 缓冲配置(提升性能)
        proxy_buffering    on;       # 启用缓冲
        proxy_buffer_size  4k;      # 响应头缓冲大小
        proxy_buffers      8 4k;    # 响应体缓冲(8个,每个4k)
    }

    # 代理到特定路径 —— 末尾 / 会替换 location 路径部分
    location /api/ {
        # 请求 /api/users 会被代理到 http://127.0.0.1:8080/users
        # 因为末尾有 /,所以 /api/ 被替换为 /
        proxy_pass http://127.0.0.1:8080/;
    }
}

5.3 WebSocket 代理详解

WebSocket 是一种双向通信协议,与传统HTTP轮询不同,它允许服务器主动推送数据。Nginx从1.3版本开始支持WebSocket代理。

WebSocket与HTTP的区别

  • HTTP:请求-响应模式,客户端先发请求,服务器才能响应
  • WebSocket:建立连接后,客户端和服务器都可以随时发送数据
  • WebSocket通过HTTP的Upgrade机制建立
location /ws/ {
    proxy_pass http://127.0.0.1:8000/ws/;   # WebSocket后端地址

    # WebSocket 必须配置这三个指令
    proxy_http_version 1.1;                              # 必须使用HTTP/1.1
    proxy_set_header Upgrade    $http_upgrade;           # 升级协议
    proxy_set_header Connection "upgrade";               # 升级连接

    # 超时(WebSocket是长连接,需要更长超时)
    proxy_read_timeout 86400s;   # 24小时
    proxy_send_timeout 86400s;
}

5.4 uWSGI 代理(Python应用)

uWSGI 是Python Web应用的常见部署方式,通常配合Nginx作为前端代理。

location / {
    include     /etc/nginx/uwsgi_params;    # 引入uWSGI参数定义
    uwsgi_pass  127.0.0.1:5000;             # uWSGI监听地址
}

6. 负载均衡

6.1 负载均衡概念详解

负载均衡(Load Balancing) 是一种将传入的网络流量分配到多个后端服务器的技术,目的是优化资源使用、最大化吞吐量、减少延迟、避免单点故障。

概念 解释
upstream Nginx中定义后端服务器组的配置块,所有负载均衡策略都在此定义
后端服务器(Backend) 实际处理请求的应用服务器
负载均衡算法 决定请求分发到哪个后端的策略
┌─────────────────────────────────────────────────────────┐
│           🔄 Nginx 负载均衡架构                          │
│                                                         │
│                    Client                               │
│                      │                                   │
│                      ▼                                   │
│              ┌────────────┐                             │
│              │     🟣     │                             │
│              │   Nginx    │                             │
│              │  (LB)      │                             │
│              └─────┬──────┘                             │
│                    │                                    │
│        ┌───────────┼───────────┐                       │
│        ▼           ▼           ▼                       │
│   ┌─────────┐ ┌─────────┐ ┌─────────┐                  │
│   │ 🔵      │ │ 🔵      │ │ 🔵      │                  │
│   │Backend1 │ │Backend2 │ │Backend3 │                  │
│   │ :8080   │ │ :8081   │ │ :8082   │                  │
│   └─────────┘ └─────────┘ └─────────┘                  │
│                                                         │
└─────────────────────────────────────────────────────────┘

6.2 轮询(Round Robin)详解

轮询是Nginx默认的负载均衡策略,按顺序将请求分配到每台服务器,每个服务器获得大致相等的请求数量。

  • 优点:简单、均匀分布、无需额外配置
  • 缺点:不考虑服务器性能差异、不考虑当前负载
http {
    # 定义上游服务器组
    upstream backend {
        server 127.0.0.1:8080;    # 第1台服务器
        server 127.0.0.1:8081;    # 第2台服务器
        server 127.0.0.1:8082;    # 第3台服务器
        server 127.0.0.1:8083;    # 第4台服务器
        # 请求会按 1→2→3→4→1→2... 循环分配
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://backend;  # 使用backend服务器组
        }
    }
}

6.3 加权轮询详解

加权轮询允许为每台服务器设置权重值,性能更好的服务器设置更高权重,获得更多请求。

  • weight参数:权重值,默认1,数值越大获得的请求比例越高
  • 计算方式:若服务器A weight=5,服务器B weight=1,则A获得5/6的请求,B获得1/6
upstream backend {
    server 127.0.0.1:8080 weight=5;      # 权重5,每6个请求中获得5个
    server 127.0.0.1:8081 weight=3;      # 权重3,每6个请求中获得3个
    server 127.0.0.1:8082 weight=2;      # 权重2,每6个请求中获得2个
    server 127.0.0.1:8083;               # 权重1(默认),每6个请求中获得1个
}

6.4 最少连接(Least Connections)详解

最少连接策略将请求分配给当前连接数最少的服务器,适合长时间连接的场景(如WebSocket、数据库连接池)。

upstream backend {
    least_conn;                          # 启用最少连接策略
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
}

6.5 IP Hash详解

IP Hash使用客户端IP的哈希值来决定分配到哪台服务器,同一IP的请求始终发送到同一台服务器。

  • 优点:会话保持,用户状态可以保存在后端服务器
  • 缺点:服务器数量变化时,大量用户可能被重新分配
upstream backend {
    ip_hash;                             # 启用IP Hash策略
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
}

6.6 URL Hash(权重Hash)详解

URL Hash使用请求URL的哈希值来分配请求,相同URL的请求会发送到同一台服务器。consistent参数启用一致性哈希,服务器变化时影响范围更小。

upstream backend {
    hash $request_uri consistent;       # 基于URI的Hash,consistent减少重分配
    server 127.0.0.1:8080;
    server 127.0.0.1:8081;
}

6.7 健康检查详解

Nginx提供被动健康检查功能,当后端服务器连续失败达到一定次数后,会被标记为不可用。

参数 说明 默认值
max_fails 失败次数达到此值则标记为不可用 1
fail_timeout 不可用持续时间,之后重新尝试 10秒
backup 标记为备份服务器,仅在主服务器全挂时启用 -
down 永久标记为不可用 -
upstream backend {
    server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;  # 30秒内失败3次,标记为不可用,30秒后重试
    server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8082 backup;        # 备份服务器,只有前两个都不可用时才会使用
    server 127.0.0.1:8083 down;          # 永久不可用
}

7. HTTPS 配置

7.1 HTTPS与SSL概念详解

HTTPS(Hypertext Transfer Protocol Secure) 是HTTP的安全版本,通过SSL/TLS协议加密传输数据。SSL(Secure Sockets Layer) 是早期的加密协议,已被TLS(Transport Layer Security) 取代,但人们仍习惯用SSL称呼。

概念 解释
SSL证书 证明服务器身份的数字证书,由可信CA颁发
证书链(fullchain.pem) 包含服务器证书和中间CA证书
私钥(privkey.pem) 用于解密的对称密钥,必须保密
TLS协议 SSL的升级版,目前主流版本是TLSv1.2和TLSv1.3
加密套件(Cipher Suite) 加密算法的组合,决定加密强度
OCSP Stapling 服务器直接提供证书状态检查结果,加速验证
会话缓存(Session Cache) 复用已建立的SSL会话,避免重复握手
server {
    listen 443 ssl;                              # 监听443端口,启用SSL
    server_name example.com www.example.com;

    # SSL证书配置
    ssl_certificate     /etc/nginx/ssl/fullchain.pem;    # 证书链文件(包含服务器证书+中间CA)
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;     # 私钥文件(必须保密)

    # TLS协议版本(推荐只启用TLSv1.2和TLSv1.3,禁用旧版SSL)
    ssl_protocols TLSv1.2 TLSv1.3;

    # 加密套件配置(使用现代加密算法)
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers on;   # 服务器端加密套件优先(客户端次之)

    # SSL会话配置(提升性能)
    ssl_session_cache shared:SSL:10m;     # 共享会话缓存,大小10MB
    ssl_session_timeout 1d;              # 会话缓存有效期1天
    ssl_session_tickets off;              # 禁用会话票证(更安全)

    # OCSP Stapling(在线证书状态协议 stapling)
    ssl_stapling on;                      # 启用OCSP stapling
    ssl_stapling_verify on;              # 验证OCSP响应
    resolver 8.8.8.8 8.8.4.4 valid=300s; # DNS解析器(用于查询OCSP服务器)
    resolver_timeout 5s;                 # DNS查询超时
}

7.2 HTTP 跳转 HTTPS 详解

将所有HTTP请求强制跳转到HTTPS,提高安全性。

# HTTP服务器 —— 监听80端口,处理所有HTTP请求
server {
    listen 80;                              # HTTP标准端口
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;     # 301永久重定向到HTTPS
}

# HTTPS服务器 —— 监听443端口
server {
    listen 443 ssl;                         # SSL启用
    server_name example.com www.example.com;
    # ... SSL配置 ...
}

7.3 Let's Encrypt 免费证书详解

Let's Encrypt 是一个非营利CA,提供免费的SSL/TLS证书。certbot是其官方客户端,可自动申请和续期证书。

# 安装 certbot 和 Nginx 插件
sudo apt install certbot python3-certbot-nginx

# 申请证书并自动配置 Nginx(推荐)
sudo certbot --nginx -d example.com -d www.example.com

# 单独申请证书(不修改nginx配置)
sudo certbot certonly --nginx -d example.com -d www.example.com

# 测试自动续期(实际续期由cron/systemd timer执行)
sudo certbot renew --dry-run

7.4 双向认证(mTLS)详解

双向认证(mTLS,Mutual TLS) 除了服务器提供证书验证身份外,服务器也要求客户端提供证书验证身份。适用于企业内部系统、API安全等场景。

server {
    listen 443 ssl;
    server_name example.com;

    # 客户端证书验证配置
    ssl_client_certificate /etc/nginx/ssl/ca.crt;     # CA证书(用于验证客户端证书)
    ssl_verify_client on;                             # 要求客户端提供证书(可选值:on/optional/off)

    location / {
        # 检查客户端证书验证状态
        if ($ssl_client_verify != SUCCESS) {
            return 403;   # 证书验证失败返回403
        }
    }
}
ssl_verify_client 值 说明
off 不要求客户端证书(默认)
on 要求客户端证书,验证失败拒绝连接
optional 要求客户端证书,但验证失败仍允许继续(可通过变量判断)

8. 高级特性

8.1 Rewrite 规则详解

Rewrite 用于修改请求的URI,常用于URL重写、重定向、旧链接跳转等场景。

概念 解释
rewrite指令 执行URL重写,可使用正则表达式捕获分组
permanent 301永久重定向,浏览器会缓存
redirect 302临时重定向,浏览器不缓存
last 重写后重新搜索location(内部重写)
break 停止rewrite匹配,使用当前结果
# 永久重定向(301)—— 告诉浏览器和搜索引擎这是永久变更
rewrite ^/old-page$ /new-page permanent;

# 临时重定向(302)—— 用于临时跳转
rewrite ^/old-page$ /new-page redirect;

# 正则重写(捕获分组)—— 将 /blog/2024/01/article 重写为 /article-article-2024-01
rewrite ^/blog/(\d+)/(\d+)/(.+)$ /article/$3-$1-$2 permanent;

# 内部重写(不改变URL)—— URL不变,但内部转发到目标文件
rewrite ^/search/(.+)$ /search.php?q=$1 last;

# 标志位说明
# last  - 重写后重新匹配location(用于内部跳转)
# break - 停止rewrite匹配(用于内部重写)
# redirect - 临时重定向(302)
# permanent - 永久重定向(301)

8.2 Nginx变量详解

Nginx提供了丰富的内置变量,可以在配置中引用这些值。

变量 说明 示例值
$host 请求行中的域名或server_name匹配的值 example.com
$uri 请求的URI(不含查询参数,不包含开头/) /index.html
$request_uri 完整原始URI(含查询参数) /index.html?foo=bar
$args 查询字符串(?后的部分) foo=bar&baz=qux
$remote_addr 客户端IP地址 192.168.1.100
$http_header 任意请求头(-换成_,大写变小写) $http_user_agent
$scheme 协议方案 httphttps
$document_root 当前请求的root指令值 /var/www/html
$server_name 匹配的server名称 example.com
$request_method 请求方法 GETPOST
$request_filename 当前请求文件的完整路径 /var/www/html/index.html
$status 响应状态码 200404502
$body_bytes_sent 发送给客户端的字节数 1234
$request_time 请求处理时间(秒) 0.052

8.3 条件判断详解

Nginx支持基于IP、User-Agent、Cookie等条件进行访问控制。

# 基于IP限制访问
location /admin/ {
    allow 192.168.1.0/24;    # 允许这个IP段
    allow 10.0.0.0/8;        # 允许这个IP段
    deny all;                 # 拒绝其他所有IP
}

# 基于User-Agent限制(阻止爬虫)
if ($http_user_agent ~* "bot|spider|crawl") {
    return 403;              # 返回禁止访问
}

# 基于Cookie限制
if ($cookie_session ~* "invalid") {
    return 403;
}

# 基于请求方法限制
location /api/ {
    limit_except GET POST PUT DELETE {  # 只允许这些方法
        deny all;                        # 其他方法拒绝
    }
}

8.4 速率限制详解

Nginx提供两种限流方式:请求速率限制(limit_req)并发连接限制(limit_conn)

概念 解释
limit_req_zone 定义限流区域(共享内存),存储请求计数
$binary_remote_addr 二进制格式的客户端IP(比$remote_addr更省内存)
rate 速率,单位r/s(每秒请求数)或r/m(每分钟请求数)
burst 突发允许的请求数
nodelay 不延迟处理突发请求
limit_req_status 超出限制时返回的状态码
# 定义请求速率限制区域(基于IP)
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

# 定义并发连接限制区域
limit_conn_zone $binary_remote_addr zone=connlimit:10m;

server {
    location /api/ {
        # 应用限流:速率10r/s,突发允许20个请求,不延迟
        limit_req zone=mylimit burst=20 nodelay;
        limit_req_status 429;    # 超限时返回429 Too Many Requests
    }

    location / {
        # 限制每个IP最多10个并发连接
        limit_conn connlimit 10;
        limit_conn_status 429;
    }
}

8.5 缓存配置详解

Nginx可以缓存后端服务器的响应,减少对后端的请求,提升响应速度。

概念 解释
proxy_cache_path 定义缓存存储路径和参数
levels 缓存目录层级深度(如1:2表示两级目录)
keys_zone 缓存元数据共享内存区域(名称:大小)
max_size 缓存最大磁盘空间
inactive 缓存有效期(不活跃时间后自动清除)
use_temp_path 是否使用临时目录(off表示直接写入缓存)
proxy_cache 启用的缓存区域名称
proxy_cache_valid 不同状态码的缓存时间
proxy_cache_key 缓存键的组成(决定缓存命中条件)
$upstream_cache_status 缓存状态变量(HIT/MISS/EXPIRED等)
# 定义代理缓存路径和参数
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m
                 max_size=1g inactive=60m use_temp_path=off;

server {
    location / {
        proxy_pass http://backend;

        # 启用缓存
        proxy_cache my_cache;            # 使用名为my_cache的缓存

        # 缓存有效期(按状态码区分)
        proxy_cache_valid 200 60m;       # 200响应缓存60分钟
        proxy_cache_valid 404 1m;        # 404响应缓存1分钟

        # 缓存键(决定缓存如何命中)
        proxy_cache_key "$scheme$request_method$host$request_uri";

        # 添加缓存状态头(方便调试)
        add_header X-Cache-Status $upstream_cache_status;
    }
}

9. 性能优化

9.1 Worker 进程配置详解

Worker进程是实际处理请求的进程,其配置直接影响Nginx并发性能。

概念 解释
worker_processes Master进程fork的Worker数量,auto表示自动设置为CPU核心数
worker_cpu_affinity 将Worker进程绑定到特定CPU核心,减少进程切换开销
worker_rlimit_nofile 单个Worker可打开的最大文件描述符数量
# 全局块
worker_processes auto;              # 自动设置为CPU核心数
worker_cpu_affinity auto;           # CPU绑定(Linux特有,减少进程切换)

# 每个Worker允许的连接数(需配合系统ulimit)
worker_rlimit_nofile 65535;         # 最大文件描述符数

9.2 Events 块优化详解

Events块配置连接处理方式,对高并发性能至关重要。

概念 解释
worker_connections 单个Worker进程可处理的最大并发连接数
use epoll 使用epoll事件模型(Linux 2.6+,高效处理大量并发)
multi_accept 一次accept()接受多个连接,减少系统调用
events {
    worker_connections 65535;       # 单个Worker最大连接数
    use epoll;                     # Linux高效事件模型(BSD用kqueue)
    multi_accept on;               # 一次接受多个新连接
}

9.3 HTTP 块优化详解

HTTP块包含大量性能优化配置。

概念 解释
sendfile 启用零拷贝文件传输,减少内核态/用户态切换
tcp_nopush 在sendfile开启时,等待多个数据包后一起发送(减少包头开销)
tcp_nodelay 禁用Nagle算法,降低小数据包的延迟
keepalive_timeout keep-alive连接保持时间
keepalive_requests 单个keep-alive连接可处理的最大请求数
gzip 启用gzip压缩,减小传输大小
gzip_comp_level 压缩级别(1-9,越高压缩率越高但CPU开销越大)
gzip_types 需要压缩的MIME类型
client_body_buffer_size 客户端请求体缓冲区大小
client_max_body_size 客户端最大请求体大小(上传文件限制)
open_file_cache 文件描述符缓存,减少磁盘IO
http {
    # 文件传输优化
    sendfile on;                   # 零拷贝技术
    tcp_nopush on;                 # 配合sendfile,攒包发送
    tcp_nodelay on;                # 禁用Nagle算法,降低延迟

    # 连接优化
    keepalive_timeout 65;          # keep-alive超时(秒)
    keepalive_requests 1000;       # 单连接最大请求数

    # 压缩配置
    gzip on;                        # 启用gzip压缩
    gzip_vary on;                  # 添加Vary头(代理缓存需)
    gzip_proxied any;              # 代理的响应也压缩
    gzip_comp_level 6;              # 压缩级别6(平衡压缩率和CPU)
    gzip_types text/plain text/css text/xml application/json
               application/javascript application/rss+xml application/atom+xml;
    gzip_min_length 1000;           # 只有大于1000字节才压缩

    # 缓冲区配置
    client_body_buffer_size 16k;    # 请求体缓冲
    client_header_buffer_size 1k;   # 请求头缓冲
    client_max_body_size 8m;        # 最大请求体(上传限制)
    large_client_header_buffers 4 8k;  # 大请求头缓冲(数量 大小)

    # 打开文件缓存(减少磁盘IO)
    open_file_cache max=65535 inactive=20s;    # 最大缓存文件数和不活跃时间
    open_file_cache_valid 30s;                 # 缓存验证间隔
    open_file_cache_min_uses 2;               # 缓存文件的最小使用次数
    open_file_cache_errors on;                # 缓存文件不存在错误
}

9.4 FastCGI 优化(PHP)详解

FastCGI是Nginx与PHP通信的协议(php-fpm),需要合理配置缓冲区保持连接。

概念 解释
fastcgi_pass PHP-FPM的地址(可以是TCP端口或Unix socket)
fastcgi_keep_conn 保持FastCGI连接复用,减少连接开销
fastcgi_connect_timeout 与PHP-FPM建立连接的超时时间
fastcgi_send_timeout 向PHP-FPM发送请求的超时时间
fastcgi_read_timeout 等待PHP-FPM响应的超时时间
fastcgi_buffer_size 读取响应头的缓冲区大小
fastcgi_buffers 响应体缓冲区(数量 大小)
upstream php_backend {
    server 127.0.0.1:9000;
    keepalive 16;                  # 保持16个连接到PHP-FPM
}

server {
    location ~ \.php$ {
        fastcgi_pass php_backend;
        fastcgi_keep_conn on;      # 保持连接复用

        # 超时配置
        fastcgi_connect_timeout 60s;
        fastcgi_send_timeout 60s;
        fastcgi_read_timeout 60s;

        # 缓冲区配置
        fastcgi_buffer_size 4k;     # 响应头缓冲
        fastcgi_buffers 8 4k;      # 响应体缓冲(8个,每个4k)
        fastcgi_busy_buffers_size 8k;  # 忙碌时缓冲大小
        fastcgi_temp_file_write_size 8k;  # 写入临时文件大小

        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

10. 故障排查

10.1 常用命令详解

命令 说明 使用场景
nginx -t 测试配置语法是否正确 重载配置前必用
nginx -T 测试配置并打印完整配置 调试include文件问题
nginx -s reload 发送HUP信号重载配置 更新配置不中断服务
nginx -s stop 发送TERM信号立即停止 强制停止
nginx -s quit 发送QUIT信号优雅停止 等待请求处理完再停止
nginx -v 显示版本号 查看版本
nginx -V 显示版本、编译参数、配置参数 查看编译时选项
nginx -c 指定配置文件路径 使用非默认配置启动

10.2 日志分析详解

Nginx有两大日志文件:

  • access.log(访问日志):记录每个请求的详细信息
  • error.log(错误日志):记录服务器错误和警告
# 实时查看访问日志(-f 跟踪文件变化)
sudo tail -f /var/log/nginx/access.log

# 实时查看错误日志
sudo tail -f /var/log/nginx/error.log

# 分析访问日志 - 统计最常访问的URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# 分析访问日志 - 统计TOP IP(找出异常访问源)
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

# 查找错误日志中的错误
grep -i error /var/log/nginx/error.log

# 分析慢请求(需在log_format中配置$request_time)
awk '{if($NF>1) print $NF, $7}' /var/log/nginx/access.log | sort -rn | head -20

10.3 常见错误及解决方案详解

HTTP状态码 错误名称 原因分析 解决方案
400 Bad Request 请求头过大、请求格式错误 增大large_client_header_buffers
403 Forbidden 文件权限不足、SELinux限制、deny规则 检查文件权限、allow/deny规则
404 Not Found 文件不存在、root路径错误 检查root路径、try_files配置
502 Bad Gateway 后端服务器无响应、超时 检查后端服务、proxy_pass配置
503 Service Unavailable 后端服务器全挂、连接数满 检查后端健康状态、backup服务器
504 Gateway Timeout 后端响应超时 增加proxy_read_timeout
413 Request Entity Too Large 上传文件过大 增加client_max_body_size
499 Client Closed Request 客户端提前关闭连接 检查超时设置、客户端行为

10.4 压力测试详解

压力测试用于评估Nginx在高并发下的性能表现。

工具 说明 常用参数
ab(Apache Bench) Apache自带的简单压测工具 -n总请求数,-c并发数
wrk 高性能HTTP压测工具 -t线程数,-c连接数,-d持续时间
siege 多线程压测工具 -c并发数,-t持续时间
# ab压测:10000个请求,100个并发
ab -n 10000 -c 100 http://localhost/

# wrk压测:12线程,400连接,持续30秒
wrk -t12 -c400 -d30s http://localhost/

# siege压测:100并发,持续30秒
siege -c 100 -t 30s http://localhost/

10.5 调试技巧详解

# 启用调试级别日志(记录最详细的日志信息)
error_log /var/log/nginx/error.log debug;

# 在特定location中记录详细访问日志
location / {
    access_log /var/log/nginx/detail.log main;
    body_log on;       # 记录请求体
    header_log on;     # 记录请求头
}

# 模拟错误响应(测试监控告警)
location /test {
    return 500 "Test Error";
}

📚 附录

A. 常用配置指令速查表

指令 说明 可用位置
listen 监听端口,可指定IP和端口,如800.0.0.0:80443 ssl server
server_name 服务器域名,支持精确匹配、通配符、正则表达式 server
root 文档根目录,定义网站文件的物理路径 server, location
location URL路由块,根据URI路径匹配并处理请求 server
proxy_pass 反向代理目标地址,转发请求到后端服务器 location
proxy_set_header 设置转发给后端的请求头(如Host、Client-IP等) http, server, location
ssl_certificate SSL证书文件路径(包含证书链) server
ssl_certificate_key SSL私钥文件路径 server
rewrite URL重写规则,可用于重定向或内部路由 server, location
try_files 依次尝试文件/目录,最后回退到指定URI或状态码 location
error_page 定义错误页面,当发生指定错误码时显示 http, server, location
limit_req 请求速率限制,控制每秒/每分钟请求数 location
limit_conn 并发连接数限制,控制单个IP的并发连接数 location
gzip 启用gzip压缩,减小传输大小 http, server, location
add_header 向响应添加自定义HTTP头部 http, server, location
expires 设置Cache-Control和Expires头,控制浏览器缓存时间 http, server, location

B. 参考资源

资源 说明 链接
📘 官方文档 Nginx官方文档,最权威的技术参考 https://nginx.org/en/docs/
📘 官方教程 Nginx入门教程,适合初学者 https://nginx.org/en/docs/beginners_guide.html
📘 SSL配置指南 Mozilla的SSL配置推荐(安全加固参考) https://ssl-config.mozilla.org/
📘 Let's Encrypt 免费SSL证书申请和管理 https://letsencrypt.org/
📘 Certbot Let's Encrypt官方客户端 https://certbot.eff.org/

💡 提示:建议使用 nginx -t 验证配置后再重载!

🔐 安全提醒:生产环境务必启用 HTTPS,定期更新 SSL 证书!


📅 文档更新时间:2026/05/18

posted @ 2026-07-07 18:55  RK5123153  阅读(33)  评论(0)    收藏  举报