🚀 Nginx 软件设计架构与详细教程

IT 技术 81 阅读 更新于 2026-09-04 06:47

从架构原理到生产实践的完整指南 — 涵盖高性能 Web 服务器、反向代理与负载均衡

📋 目录索引

一、Nginx 概述

1.1 什么是 Nginx?

Nginx 简介

Nginx(发音为 "engine-x")是一个开源的、高性能的 HTTP 和反向代理服务器,同时也提供了 IMAP/POP3/SMTP 邮件代理服务。它由俄罗斯程序员 Igor Sysoev 于 2002 年开始开发,2004 年正式发布,旨在解决 C10K 问题(同时处理 10,000 个并发连接)。

💡 核心特点:

Nginx 采用异步非阻塞的事件驱动架构,相比传统的 Apache 进程/线程模型,在高并发场景下具有显著的性能优势和更低的资源消耗。

主要功能

🌐 Web 服务器

高性能静态文件服务,支持 HTTP/2、HTTPS、gzip 压缩等

🔄 反向代理

将客户端请求转发到后端服务器,隐藏后端拓扑

⚖️ 负载均衡

支持多种负载均衡算法,分发流量到多个后端

📦 静态文件服务

高效的静态内容缓存与分发

🔐 SSL/TLS 终端

SSL 卸载、证书管理、HTTPS 加速

📊 缓存代理

反向代理缓存,减少后端压力

市场份额

根据 W3Techs 的统计数据,Nginx 在全球活跃网站中的使用率超过 30%,在流量最大的 1000 个网站中使用率超过 40%,是全球使用最广泛的 Web 服务器之一。

特性NginxApache
架构模型事件驱动(异步非阻塞)进程/线程(多进程模型)
并发连接数万级轻松处理数千级(受进程限制)
内存消耗极低(每连接数 KB)较高(每连接数 MB)
静态文件处理极快较快
动态内容处理需要配合 FastCGI/uWSGI内置模块支持
配置复杂度简洁清晰功能丰富但较复杂

1.2 Nginx 版本与许可

版本类型

  • Nginx OSS(开源版):采用 2-clause BSD 许可证,完全免费开源
  • Nginx Plus(商业版):F5 公司(2019 年收购 Nginx)提供的企业级版本,包含额外功能和技术支持
  • Nginx 版本命名规则:偶数版本号(如 1.24、1.26)为稳定版,奇数版本号(如 1.25、1.27)为开发版

版本发布策略

Nginx 遵循大约每年发布一个稳定主版本的节奏,每个稳定版本会维护约 18 个月的安全更新。建议生产环境使用最新的稳定版本。

ℹ️ 版本选择建议:

截至 2026 年,推荐使用 Nginx 1.26.x 或 1.28.x 稳定版本。

二、软件设计架构

2.1 总体架构设计

架构设计理念

Nginx 的架构设计核心思想是事件驱动 + 多进程模型,这是它能够高效处理大量并发连接的关键。与 Apache 的每请求一个进程/线程不同,Nginx 使用了 reactor 模式,通过少量的 worker 进程即可处理成千上万的并发连接。

┌─────────────────────────────────────────────────────────────────┐ │ Nginx 架构总览 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Master │ │ Worker 1 │ │ Worker N │ │ │ │ Process │────▶│ Process │ │ Process │ │ │ │ (管理进程) │ │ (工作进程) │ │ (工作进程) │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ │ │ │ │ │ ┌─────┴─────┐ ┌─────┴─────┐ │ │ │ │ Event │ │ Event │ │ │ │ │ Loop │ │ Loop │ │ │ │ └─────┬─────┘ └─────┬─────┘ │ │ │ │ │ │ │ ┌──────┴──────┐ ┌─────┴─────┐ ┌─────┴─────┐ │ │ │ Cache │ │ epoll/ │ │ epoll/ │ │ │ │ Manager │ │ kqueue │ │ kqueue │ │ │ └─────────────┘ └───────────┘ └───────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘

核心组件说明

组件职责数量
Master Process(主进程)读取和验证配置文件、创建/管理 worker 进程、发送信号、日志轮转管理1
Worker Process(工作进程)处理实际的客户端连接、执行事件循环、处理请求通常等于 CPU 核心数
Cache Loader(缓存加载器)启动时将缓存元数据加载到内存中1(按需)
Cache Manager(缓存管理器)定期检查缓存条目有效性,清理过期条目1(按需)

2.2 Master-Worker 进程模型详解

Master Process(主进程)

主进程以 root 权限运行,负责以下工作:

  • 读取配置文件:解析 nginx.conf 及其引用的配置文件
  • 创建 worker 进程:fork 出指定数量的 worker 子进程
  • 信号处理
    • SIGTERM/SIGINT - 快速关闭
    • SIGQUIT - 优雅关闭
    • SIGHUP - 重新加载配置文件
    • SIGUSR1 - 重新打开日志文件
    • SIGUSR2 - 平滑升级(热重启)
  • 监控 worker 进程:当 worker 异常退出时自动重启新的 worker
  • 特权操作:绑定端口、创建 PID 文件等需要 root 权限的操作

Worker Process(工作进程)

工作进程以非特权用户身份运行(通常是 nginx 或 www-data),负责:

  • 事件循环:每个 worker 独立运行自己的事件循环
  • 连接处理:处理 TCP/UDP 连接的建立、数据传输、关闭
  • 请求处理:解析 HTTP 请求,调用相应的处理模块
  • 负载均衡竞争:多个 worker 通过 accept_mutex 或 reuseport 竞争新连接

┌─────────────────────────────────────────────────────────────┐ │ Master 进程管理流程 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ nginx -c /etc/nginx/nginx.conf │ │ │ │ │ ▼ │ │ ┌──────────────┐ │ │ │ fork() │ │ │ │ Master │ │ │ └──────┬───────┘ │ │ │ │ │ ┌────┼────┬────────┐ │ │ ▼ ▼ ▼ ▼ │ │ ┌───┐┌───┐┌───┐ ┌───┐ │ │ │ W1││ W2││ W3│ │ Wn│ ← Worker 进程(非特权用户) │ │ └───┘└───┘└───┘ └───┘ │ │ │ │ 信号传递: Master ──signal──▶ Worker │ │ Worker 退出: Worker ──exit──▶ Master (自动重启) │ │ │ └─────────────────────────────────────────────────────────────┘

进程间通信(IPC)

Nginx 使用以下方式进行进程间通信:

  • Unix Signal(信号):主进程向 worker 发送控制信号
  • Unix Domain Socket:用于 worker 之间的通信和共享数据
  • 共享内存:用于 worker 之间共享配置、状态等信息
  • 文件锁:用于 accept_mutex 互斥机制

2.3 事件驱动模型(Event-Driven)

事件驱动架构核心

Nginx 使用异步非阻塞 I/O + 多路复用的事件驱动模型,这是其高性能的关键所在。与传统同步阻塞 I/O 不同,事件驱动模型不会因为等待 I/O 而阻塞整个进程。

🔑 关键概念:

每个 worker 进程在同一时间只运行一个事件循环,但可以通过非阻塞 I/O 同时处理成千上万个连接。

I/O 多路复用机制

Nginx 支持多种操作系统提供的高效 I/O 多路复用机制:

操作系统I/O 多路复用机制特点
Linuxepoll时间复杂度 O(1),适合大规模连接
FreeBSD/macOSkqueue高效的 BSD 系统事件通知
Solaris/dev/pollSolaris 特有
所有平台select/poll通用但性能较差,作为备选

事件处理流程

┌─────────────────────────────────────────────────────┐ │ Worker 事件循环流程 │ ├─────────────────────────────────────────────────────┤ │ │ │ ┌──────────┐ │ │ │ 等待 │◄─────────────────────────┐ │ │ │ 事件 │ │ │ │ └────┬─────┘ │ │ │ │ (epoll_wait 返回) │ │ │ ▼ │ │ │ ┌──────────┐ │ │ │ │ 遍历 │ │ │ │ │ 就绪事件│ │ │ │ └────┬─────┘ │ │ │ │ │ │ │ ▼ │ │ │ ┌──────────┐ ┌──────────┐ │ │ │ │ 处理 │────▶│ 处理 │────... │ │ │ │ 事件 A │ │ 事件 B │ │ │ │ └────┬─────┘ └──────────┘ │ │ │ │ │ │ │ ▼ │ │ │ ┌──────────┐ │ │ │ │ 检查 │──── 没有更多事件 ────────┘ │ │ │ 定时器 │ │ │ └──────────┘ │ │ │ └─────────────────────────────────────────────────────┘

连接状态机

每个连接在 Nginx 中被表示为一个 ngx_connection_t 结构体,通过状态机管理其生命周期:

接受连接

读取请求头

解析请求

处理请求

发送响应

关闭/保持

每个阶段的处理函数都注册为事件回调,当 I/O 就绪时自动触发,避免了线程切换和锁竞争的开销。

2.4 内存管理机制

内存池(Memory Pool)

Nginx 使用了自定义的内存池管理系统,避免了频繁调用 malloc/free 带来的性能开销和内存碎片问题。

  • 池化分配:预先分配一块大内存,后续从小块中分配
  • 自动释放:请求处理完成后,整个内存池一次性释放
  • 对齐分配:内存按指针对齐,提高 CPU 缓存命中率
  • 大内存处理:超过池大小的分配使用系统 malloc,记录在链表中随池释放

内存池结构

struct ngx_pool_s {
    ngx_pool_data_t    d;        /* 内存池数据 */
    size_t             max;      /* 最大块大小 */
    ngx_pool_t        *current;  /* 当前分配池 */
    ngx_chain_t       *chain;    /* 大内存链表 */
    ngx_pool_large_t  *large;    /* 大内存分配列表 */
    ngx_pool_cleanup_t *cleanup; /* 清理回调 */
    ngx_log_t         *log;      /* 日志 */
};

缓冲区管理

Nginx 使用 ngx_buf_t 结构体管理数据缓冲区,支持:

  • 内存缓冲区:数据存储在内存中
  • 文件缓冲区:数据引用磁盘文件,使用 sendfile 零拷贝传输
  • 链式缓冲区:通过 ngx_chain_t 将多个缓冲区串联

⚡ Zero-Copy(零拷贝):

Nginx 在发送静态文件时,使用 sendfile() 系统调用,数据直接从磁盘文件传输到网络套接字,避免了内核空间到用户空间的拷贝,极大提升了性能。

2.5 请求处理流水线

11 个处理阶段(Phases)

Nginx 将 HTTP 请求的处理过程分为 11 个阶段(Phases),每个阶段执行特定的功能,模块可以在对应阶段注册处理函数:

阶段名称功能
1POST_READ读取请求后首先执行,如获取客户端真实IP
2SERVER_REWRITEserver 级别的 URL 重写
3FIND_CONFIG根据 URI 查找匹配的 location(不可插入模块)
4REWRITElocation 级别的 URL 重写
5POST_REWRITEURL 重写后重新查找 location(不可插入模块)
6PREACCESS访问控制前准备,如限流、连接限制
7ACCESS访问控制,如 allow/deny 规则
8POST_ACCESS访问控制后处理(如 satisfy any)
9PRECONTENT内容处理前的准备
10CONTENT生成响应内容(核心阶段)
11LOG记录日志

请求进入 │ ▼ POST_READ ──▶ SERVER_REWRITE ──▶ FIND_CONFIG ──▶ REWRITE │ ┌─────────────────────────────────────────────────┘ ▼ POST_REWRITE ──▶ PREACCESS ──▶ ACCESS ──▶ POST_ACCESS │ ┌─────────────────────────────────────────────────┘ ▼ PRECONTENT ──▶ CONTENT ──▶ LOG ──▶ 请求完成

2.6 配置解析与继承机制

配置解析流程

  1. 配置文件读取:主进程读取 nginx.conf
  2. 词法分析:将配置文件解析为 token 流
  3. 语法分析:构建配置命令树(command tree)
  4. 命令执行:按照作用域依次执行配置指令
  5. 配置合并:将不同级别的配置进行合并
  6. 配置继承(Merge)机制

    Nginx 的配置具有层级继承关系:

    main (全局配置) │ ├── http { } (HTTP 协议级) │ │ │ ├── server { } (虚拟主机级) │ │ │ │ │ └── location { } (URI 路径级) │ │ │ └── upstream { } (上游服务器组) │ ├── events { } (事件处理级) │ ├── mail { } (邮件代理级) │ └── stream { } (TCP/UDP 代理级)

    继承规则:子级配置默认继承父级配置,如果子级配置中显式定义了相同的指令,则覆盖父级配置。

    配置指令类型

    • NGX_MAIN_CONF:全局配置(如 worker_processes)
    • NGX_HTTP_MAIN_CONF:HTTP 主配置
    • NGX_HTTP_SRV_CONF:Server 配置
    • NGX_HTTP_LOC_CONF:Location 配置
    • NGX_HTTP_UPS_CONF:Upstream 配置

    2.7 连接管理与事件通知

    连接池

    Nginx 预先分配固定数量的连接对象(由 worker_connections 指令控制),所有连接从连接池中获取,用完归还,避免了动态内存分配的开销。

    struct ngx_connection_s {
        void               *data;       /* 关联的数据 */
        ngx_event_t        *read;       /* 读事件 */
        ngx_event_t        *write;      /* 写事件 */
        ngx_socket_t        fd;         /* 文件描述符 */
        ngx_recv_pt         recv;       /* 接收函数 */
        ngx_send_pt         send;       /* 发送函数 */
        struct sockaddr    *sockaddr;   /* 对端地址 */
        socklen_t           socklen;
        ngx_str_t           addr_text;  /* 地址文本 */
        /* ... */
    };

    连接竞争机制

    多个 worker 进程监听同一端口时,需要一种机制来协调谁接受新连接:

    • accept_mutex(传统方式):worker 通过互斥锁竞争 accept 权限,只有获得锁的 worker 才能调用 accept()
    • reuseport(推荐方式,Linux 3.9+):内核级别的连接分配,每个 worker 独立监听端口,由内核公平分配连接,性能更优

    🚀 性能提示:

    在 Linux 3.9+ 环境下,建议启用 reuseport 以获得更好的连接分配性能:

    listen 80 reuseport;

    三、安装与部署

    3.1 Linux 系统安装

    Ubuntu/Debian 安装

    # 更新软件包索引
    sudo apt update
    
    # 安装 Nginx
    sudo apt install nginx
    
    # 启动 Nginx
    sudo systemctl start nginx
    
    # 设置开机自启
    sudo systemctl enable nginx
    
    # 查看状态
    sudo systemctl status nginx

    使用官方仓库安装(推荐,获取最新版本)

    # 安装先决条件
    sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
    
    # 导入官方签名密钥
    curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
        | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
    
    # 添加稳定版仓库
    echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
    http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
        | sudo tee /etc/apt/sources.list.d/nginx.list
    
    # 更新并安装
    sudo apt update
    sudo apt install nginx

    CentOS/RHEL/Rocky Linux 安装

    # 使用 EPEL 仓库
    sudo yum install epel-release
    sudo yum install nginx
    
    # 或使用官方仓库,创建 /etc/yum.repos.d/nginx.repo
    [nginx-stable]
    name=nginx stable repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    
    sudo yum install nginx

    验证安装

    # 检查版本
    nginx -v
    
    # 测试配置文件语法
    sudo nginx -t
    
    # 输出示例:
    # nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    # nginx: configuration file /etc/nginx/nginx.conf test is successful

    3.2 从源码编译安装

    准备工作

    # 安装编译工具和依赖
    # Ubuntu/Debian
    sudo apt install build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev \
        libssl-dev libgd-dev libgeoip-dev libxml2-dev libxslt1-dev
    
    # CentOS/RHEL
    sudo yum groupinstall "Development Tools"
    sudo yum install pcre-devel zlib-devel openssl-devel gd-devel \
        geoip-devel libxml2-devel libxslt-devel

    下载并编译

    # 下载源码
    wget https://nginx.org/download/nginx-1.26.2.tar.gz
    tar -zxvf nginx-1.26.2.tar.gz
    cd nginx-1.26.2
    
    # 配置编译选项
    ./configure \
        --prefix=/usr/local/nginx \
        --sbin-path=/usr/local/nginx/sbin/nginx \
        --conf-path=/usr/local/nginx/conf/nginx.conf \
        --error-log-path=/var/log/nginx/error.log \
        --http-log-path=/var/log/nginx/access.log \
        --pid-path=/run/nginx.pid \
        --lock-path=/var/lock/nginx.lock \
        --user=nginx \
        --group=nginx \
        --with-http_ssl_module \
        --with-http_v2_module \
        --with-http_v3_module \
        --with-http_realip_module \
        --with-http_gzip_static_module \
        --with-http_stub_status_module \
        --with-http_image_filter_module \
        --with-http_geoip_module \
        --with-stream \
        --with-stream_ssl_module \
        --with-threads \
        --with-file-aio
    
    # 编译安装
    make -j$(nproc)
    sudo make install

    创建 systemd 服务文件

    sudo nano /etc/systemd/system/nginx.service
    
    [Unit]
    Description=The NGINX HTTP and reverse proxy server
    After=syslog.target network-online.target remote-fs.target nss-lookup.target
    Wants=network-online.target
    
    [Service]
    Type=forking
    PIDFile=/run/nginx.pid
    ExecStartPre=/usr/local/nginx/sbin/nginx -t
    ExecStart=/usr/local/nginx/sbin/nginx
    ExecReload=/usr/local/nginx/sbin/nginx -s reload
    ExecStop=/bin/kill -s QUIT $MAINPID
    PrivateTmp=true
    
    [Install]
    WantedBy=multi-user.target
    
    # 重新加载并启用
    sudo systemctl daemon-reload
    sudo systemctl enable nginx

    3.3 Docker 容器化部署

    基本使用

    # 拉取官方镜像
    docker pull nginx:latest
    
    # 运行容器
    docker run -d --name nginx \
        -p 80:80 \
        -p 443:443 \
        -v /path/to/nginx.conf:/etc/nginx/nginx.conf:ro \
        -v /path/to/conf.d:/etc/nginx/conf.d:ro \
        -v /path/to/ssl:/etc/nginx/ssl:ro \
        -v /path/to/html:/usr/share/nginx/html:ro \
        nginx:latest

    Docker Compose 配置

    version: '3.8'
    
    services:
      nginx:
        image: nginx:1.26-alpine
        container_name: nginx-proxy
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - ./nginx.conf:/etc/nginx/nginx.conf:ro
          - ./conf.d:/etc/nginx/conf.d:ro
          - ./ssl:/etc/nginx/ssl:ro
          - ./html:/usr/share/nginx/html:ro
          - ./logs:/var/log/nginx
        restart: unless-stopped
        networks:
          - webnet
    
    networks:
      webnet:
        driver: bridge

    自定义 Dockerfile

    FROM nginx:1.26-alpine
    
    # 复制自定义配置
    COPY nginx.conf /etc/nginx/nginx.conf
    COPY conf.d/ /etc/nginx/conf.d/
    
    # 复制静态文件
    COPY html/ /usr/share/nginx/html/
    
    # 安装额外工具(可选)
    RUN apk add --no-cache curl
    
    # 健康检查
    HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
        CMD curl -f http://localhost/ || exit 1
    
    EXPOSE 80 443
    
    CMD ["nginx", "-g", "daemon off;"]

    四、配置详解

    4.1 配置文件结构

    主要配置文件

    # /etc/nginx/nginx.conf - 主配置文件
    
    # ===== 全局块 =====
    user nginx;                    # 运行用户
    worker_processes auto;         # worker 进程数(auto=CPU 核心数)
    worker_rlimit_nofile 65535;   # 每个 worker 最大打开文件数
    error_log /var/log/nginx/error.log warn;  # 错误日志
    pid /run/nginx.pid;            # PID 文件
    
    # ===== events 块 =====
    events {
        worker_connections 4096;   # 每个 worker 最大并发连接数
        use epoll;                 # I/O 多路复用模型
        multi_accept on;           # 一次接受多个连接
    }
    
    # ===== http 块 =====
    http {
        include /etc/nginx/mime.types;       # MIME 类型映射
        default_type application/octet-stream;
    
        # 日志格式
        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;             # 启用 TCP_NOPUSH
        tcp_nodelay on;            # 启用 TCP_NODELAY
        keepalive_timeout 65;      # 长连接超时
        types_hash_max_size 2048;  # 类型哈希表大小
        client_max_body_size 50m;  # 客户端最大请求体
    
        # Gzip 压缩
        gzip on;
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_types text/plain text/css application/json
                   application/javascript text/xml
                   application/xml application/xml+rss text/javascript;
    
        # 包含子配置
        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
    }

    指令语法

    • 简单指令:指令名 参数;
    • 块指令:指令名 { ... }
    • 注释:# 注释内容
    • 变量:$变量名(如 $remote_addr, $uri)

    4.2 Server 虚拟主机配置

    Server Block 基本结构

    server {
        # 监听端口和地址
        listen 80;
        listen [::]:80;              # IPv6
        listen 443 ssl http2;        # HTTPS + HTTP/2
    
        # 服务器名称(支持通配符和正则表达式)
        server_name example.com www.example.com;
        server_name *.example.com;               # 通配符
        server_name ~^(?<subdomain>.+)\.example\.com$;  # 正则
    
        # 根目录
        root /var/www/example.com/html;
    
        # 默认首页
        index index.html index.htm index.php;
    
        # 字符集
        charset utf-8;
    
        # 访问日志
        access_log /var/log/nginx/example.com.access.log;
        error_log /var/log/nginx/example.com.error.log;
    
        # location 块
        location / {
            try_files $uri $uri/ =404;
        }
    
        location ~ \.php$ {
            fastcgi_pass unix:/run/php/php-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    
        # 错误页面
        error_page 404 /404.html;
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /usr/share/nginx/html;
        }
    }

    server_name 匹配规则

    匹配类型示例说明
    精确匹配example.com完全匹配域名
    前缀通配符*.example.com匹配所有子域名
    后缀通配符example.*匹配所有后缀
    正则表达式~^www\.(.+)\.com$正则匹配(~ 区分大小写,~* 不区分)

    优先级顺序:精确匹配 > 前缀通配符 > 后缀通配符 > 正则表达式

    4.3 Location 匹配规则详解

    Location 语法

    location [=|~|~*|^~|@] /uri { ... }

    匹配修饰符

    修饰符含义示例
    =精确匹配location = /api/health
    ^~前缀匹配(匹配后停止正则搜索)location ^~ /static/
    ~正则匹配(区分大小写)location ~ \.php$
    ~*正则匹配(不区分大小写)location ~* \.(jpg|png|gif)$
    @命名 location(用于内部重定向)location @fallback
    (无)普通前缀匹配location /images/

    匹配优先级(从高到低)

    1. = 精确匹配
    2. ^~ 前缀匹配(优先于正则)
    3. ~ 或 ~* 正则匹配(按配置文件顺序)
    4. 普通前缀匹配(选择最长匹配)
    5. 配置示例

      # 精确匹配首页
      location = / {
          root /var/www/html;
          index index.html;
      }
      
      # 静态文件 - 前缀匹配,不再检查正则
      location ^~ /static/ {
          alias /var/www/static/;
          expires 30d;
          add_header Cache-Control "public, immutable";
      }
      
      # 图片文件 - 正则匹配
      location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
          expires 30d;
          access_log off;
          add_header Cache-Control "public";
      }
      
      # API 路由
      location ~ ^/api/v1/ {
          proxy_pass http://api_backend;
      }
      
      # 所有其他请求
      location / {
          try_files $uri $uri/ /index.html;
      }

      ⚠️ 常见陷阱:

      location 的正则匹配是按配置文件中的顺序匹配的,第一个匹配的正则表达式生效,而非最长匹配。因此应将更具体的正则放在前面。

      4.4 常用指令速查

      文件服务相关

      指令作用示例
      root指定文件根目录(会拼接 URI)root /var/www/html;
      alias指定文件目录(替换 URI)alias /var/www/static/;
      index默认首页文件列表index index.html index.php;
      try_files尝试查找文件,失败时回退try_files $uri $uri/ =404;
      autoindex启用目录列表autoindex on;

      控制流程指令

      指令作用
      return直接返回状态码和/或 URL
      rewriteURL 重写(支持正则)
      if条件判断
      set设置变量
      map创建变量映射

      rewrite 指令详解

      # 语法: rewrite regex replacement [flag];
      
      # flag 选项:
      # last    - 停止当前处理,用新 URI 重新匹配 location
      # break   - 停止当前 rewrite 规则集的处理
      # redirect - 返回 302 临时重定向
      # permanent - 返回 301 永久重定向
      
      # 示例:
      # HTTP 转 HTTPS
      rewrite ^(.*)$ https://$host$1 permanent;
      
      # 旧 URL 重定向
      rewrite ^/old-page$ /new-page permanent;
      
      # 动态 URL 重写
      rewrite ^/user/(\d+)$ /user.php?id=$1 last;

      map 指令示例

      # 在 http 块中定义
      map $http_user_agent $is_mobile {
          default 0;
          "~*mobile|android|iphone|ipad" 1;
      }
      
      map $uri $new_uri {
          default $uri;
          "~^/blog/(.*)" /articles/$1;
          "~^/news/(.*)" /press/$1;
      }
      
      # 在 server/location 中使用
      server {
          if ($is_mobile) {
              rewrite ^ /mobile$uri;
          }
      }

      五、反向代理与负载均衡

      5.1 反向代理配置

      基本反向代理

      server {
          listen 80;
          server_name example.com;
      
          location / {
              proxy_pass http://127.0.0.1:8080;
      
              # 传递客户端信息
              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;
          }
      }

      完整的反向代理配置

      server {
          listen 80;
          server_name app.example.com;
      
          # 代理超时设置
          proxy_connect_timeout 30s;
          proxy_send_timeout 60s;
          proxy_read_timeout 60s;
      
          # 代理缓冲区
          proxy_buffering on;
          proxy_buffer_size 16k;
          proxy_buffers 4 32k;
          proxy_busy_buffers_size 64k;
      
          # 临时文件(大响应体写入磁盘)
          proxy_temp_file_write_size 64k;
          proxy_max_temp_file_size 1024m;
      
          # WebSocket 支持
          location /ws {
              proxy_pass http://websocket_backend;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection "upgrade";
              proxy_read_timeout 86400s;
          }
      
          # API 代理
          location /api/ {
              proxy_pass http://api_servers/;  # 注意末尾斜杠
      
              # 错误处理
              proxy_intercept_errors on;
              error_page 502 503 504 = @fallback;
          }
      
          location @fallback {
              proxy_pass http://backup_server;
          }
      }

      proxy_pass URL 末尾斜杠的区别

      📝 重要区别:

      例如:location /api/ 匹配请求 /api/users • 无斜杠:后端收到 /api/users • 有斜杠:后端收到 /users

      5.2 Upstream 负载均衡

      Upstream 配置

      # 定义上游服务器组
      upstream backend {
          # 负载均衡算法(默认为轮询)
          # 可用: ip_hash, hash, least_conn, random
      
          server 192.168.1.10:8080 weight=5;  # 权重
          server 192.168.1.11:8080 weight=3;
          server 192.168.1.12:8080 backup;     # 备份服务器
          server 192.168.1.13:8080 down;       # 标记为下线
      
          # 长连接(与后端保持的连接数)
          keepalive 32;
          keepalive_timeout 60s;
          keepalive_requests 1000;
      }

      负载均衡算法

      轮询(Round Robin)

      默认算法,按顺序将请求分配给服务器,支持权重。

      upstream backend {
          server 10.0.0.1:80;
          server 10.0.0.2:80;
      }

      IP Hash

      根据客户端 IP 的 hash 值分配,保证同一客户端始终访问同一服务器(会话保持)。

      upstream backend {
          ip_hash;
          server 10.0.0.1:80;
          server 10.0.0.2:80;
      }

      Least Connections

      将请求分配给当前活跃连接数最少的服务器。

      upstream backend {
          least_conn;
          server 10.0.0.1:80;
          server 10.0.0.2:80;
      }

      Hash(自定义键)

      基于自定义键值的 hash 分配,适合缓存场景。

      upstream backend {
          hash $request_uri consistent;
          server 10.0.0.1:80;
          server 10.0.0.2:80;
      }

      健康检查

      upstream backend {
          server 10.0.0.1:80 max_fails=3 fail_timeout=30s;
          server 10.0.0.2:80 max_fails=3 fail_timeout=30s;
          server 10.0.0.3:80 max_fails=3 fail_timeout=30s;
      }
      # max_fails=N: 在 fail_timeout 内允许的最大失败次数
      # fail_timeout=T: 失败统计的时间窗口,也是服务器被标记不可用后的冷却时间

      使用 upstream 的完整配置

      upstream app_backend {
          least_conn;
          server 10.0.0.1:8080 weight=5 max_fails=3 fail_timeout=30s;
          server 10.0.0.2:8080 weight=3 max_fails=3 fail_timeout=30s;
          server 10.0.0.3:8080 backup;
          keepalive 32;
      }
      
      server {
          listen 80;
          server_name app.example.com;
      
          location / {
              proxy_pass http://app_backend;
      
              # 使用 HTTP/1.1 以支持 keepalive
              proxy_http_version 1.1;
              proxy_set_header Connection "";
      
              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;
          }
      }

      5.3 代理缓存配置

      代理缓存

      # 在 http 块中定义缓存路径
      proxy_cache_path /var/cache/nginx/proxy levels=1:2
          keys_zone=my_cache:10m      # 共享内存区域名:大小
          max_size=10g                 # 最大缓存大小
          inactive=60m                 # 不活跃条目过期时间
          use_temp_path=off;           # 不使用临时路径
      
      # 在 server/location 中使用
      server {
          location / {
              proxy_pass http://backend;
      
              # 启用缓存
              proxy_cache my_cache;
              proxy_cache_valid 200 302 10m;   # 200/302 响应缓存 10 分钟
              proxy_cache_valid 404 1m;        # 404 响应缓存 1 分钟
              proxy_cache_valid any 5m;        # 其他响应缓存 5 分钟
      
              # 缓存键
              proxy_cache_key "$scheme$request_method$host$request_uri";
      
              # 缓存控制
              proxy_cache_use_stale error timeout updating http_500 http_502
                  http_503 http_504;
              proxy_cache_lock on;
              proxy_cache_lock_timeout 5s;
      
              # 添加缓存状态头
              add_header X-Cache-Status $upstream_cache_status;
      
              # 绕过缓存的条件
              proxy_cache_bypass $http_cache_control $cookie_nocache;
              proxy_no_cache $http_pragma $http_authorization;
          }
      }
      
      # $upstream_cache_status 可能的值:
      # HIT     - 缓存命中
      # MISS    - 缓存未命中
      # EXPIRED - 缓存已过期
      # STALE   - 返回过期缓存(后端不可用时)
      # UPDATING - 缓存正在更新
      # BYPASS  - 缓存被绕过

      FastCGI 缓存(适用于 PHP 等)

      fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2
          keys_zone=php_cache:10m max_size=1g inactive=60m;
      
      server {
          location ~ \.php$ {
              fastcgi_pass unix:/run/php/php-fpm.sock;
              fastcgi_index index.php;
      
              fastcgi_cache php_cache;
              fastcgi_cache_valid 200 10m;
              fastcgi_cache_key "$scheme$request_method$host$request_uri";
      
              fastcgi_cache_use_stale error timeout updating;
              add_header X-FastCGI-Cache $upstream_cache_status;
      
              include fastcgi_params;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          }
      }

      六、SSL/TLS 配置

      6.1 HTTPS 基本配置

      SSL 证书配置

      server {
          listen 443 ssl http2;
          listen [::]:443 ssl http2;
      
          server_name example.com www.example.com;
      
          # SSL 证书配置
          ssl_certificate /etc/nginx/ssl/example.com.crt;      # 证书文件(PEM 格式)
          ssl_certificate_key /etc/nginx/ssl/example.com.key;   # 私钥文件
      
          # 或使用 ECDSA 证书
          # ssl_certificate /etc/nginx/ssl/ecdsa.crt;
          # ssl_certificate_key /etc/nginx/ssl/ecdsa.key;
      
          # 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 off;  # TLS 1.3 推荐设为 off
      
          # SSL 会话缓存(提升性能)
          ssl_session_cache shared:SSL:10m;
          ssl_session_timeout 1d;
          ssl_session_tickets off;  # 安全起见可关闭
      
          # DH 参数(增强密钥交换安全)
          ssl_dhparam /etc/nginx/ssl/dhparam.pem;
      
          # OCSP Stapling
          ssl_stapling on;
          ssl_stapling_verify on;
          ssl_trusted_certificate /etc/nginx/ssl/chain.pem;
          resolver 8.8.8.8 8.8.4.4 valid=300s;
          resolver_timeout 5s;
      
          # HSTS (HTTP Strict Transport Security)
          add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
      
          # 其他安全头
          add_header X-Frame-Options "SAMEORIGIN" always;
          add_header X-Content-Type-Options "nosniff" always;
          add_header X-XSS-Protection "1; mode=block" always;
          add_header Referrer-Policy "strict-origin-when-cross-origin" always;
      
          # 网站内容
          root /var/www/example.com/html;
          index index.html;
      
          location / {
              try_files $uri $uri/ =404;
          }
      }

      HTTP 到 HTTPS 重定向

      # 方法一:return(推荐,性能更好)
      server {
          listen 80;
          listen [::]:80;
          server_name example.com www.example.com;
          return 301 https://$host$request_uri;
      }
      
      # 方法二:rewrite
      server {
          listen 80;
          server_name example.com www.example.com;
          rewrite ^(.*)$ https://$host$1 permanent;
      }

      6.2 Let's Encrypt 免费证书配置

      使用 Certbot 自动获取证书

      # 安装 Certbot 和 Nginx 插件
      sudo apt install certbot python3-certbot-nginx  # Debian/Ubuntu
      sudo yum install certbot python3-certbot-nginx  # CentOS/RHEL
      
      # 自动获取证书并配置 Nginx
      sudo certbot --nginx -d example.com -d www.example.com
      
      # 仅获取证书(手动配置)
      sudo certbot certonly --webroot -w /var/www/html -d example.com
      
      # 使用 DNS 验证(适用于通配符证书)
      sudo certbot certonly --manual --preferred-challenges dns -d "*.example.com"
      
      # 测试自动续期
      sudo certbot renew --dry-run
      
      # 证书路径(Let's Encrypt 默认)
      # 证书: /etc/letsencrypt/live/example.com/fullchain.pem
      # 私钥: /etc/letsencrypt/live/example.com/privkey.pem

      配合 Certbot 的 Nginx 配置

      server {
          listen 443 ssl http2;
          server_name example.com www.example.com;
      
          ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
          ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
      
          # Let's Encrypt 验证路径(续期时需要)
          location /.well-known/acme-challenge/ {
              root /var/www/html;
          }
      
          # 其余配置...
          location / {
              root /var/www/example.com/html;
          }
      }
      
      server {
          listen 80;
          server_name example.com www.example.com;
      
          location /.well-known/acme-challenge/ {
              root /var/www/html;
          }
      
          location / {
              return 301 https://$host$request_uri;
          }
      }

      生成 DH 参数

      # 生成 2048 位 DH 参数(推荐)
      openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
      
      # 生成 4096 位 DH 参数(更安全但更慢)
      openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096

      6.3 HTTP/2 和 HTTP/3 (QUIC) 配置

      HTTP/2 配置

      server {
          listen 443 ssl;
          http2 on;  # Nginx 1.25.1+ 新语法
          # 或旧语法: listen 443 ssl http2;
      
          server_name example.com;
          ssl_certificate /path/to/cert.pem;
          ssl_certificate_key /path/to/key.pem;
      
          # HTTP/2 特定优化
          # 多路复用默认启用,无需额外配置
          # 服务器推送(可选)
          # http2_push /static/style.css;
          # http2_push /static/app.js;
      }

      HTTP/3 (QUIC) 配置(Nginx 1.25+)

      server {
          # QUIC/HTTP3 监听
          listen 443 quic reuseport;
          listen 443 ssl;
          http2 on;
      
          server_name example.com;
      
          ssl_certificate /path/to/cert.pem;
          ssl_certificate_key /path/to/key.pem;
      
          # 告知客户端支持 HTTP/3
          add_header Alt-Svc 'h3=":443"; ma=86400';
      
          location / {
              root /var/www/html;
          }
      }

      🌐 HTTP/3 优势:

      基于 UDP 的 QUIC 协议,解决了 TCP 的队头阻塞问题,连接建立更快(0-RTT),在弱网环境下性能显著优于 TCP。

      七、性能优化

      7.1 系统级调优

      操作系统内核参数优化

      # /etc/sysctl.conf - Linux 内核参数优化
      
      # 文件系统
      fs.file-max = 2097152
      fs.inotify.max_user_watches = 524288
      
      # 网络优化
      net.core.somaxconn = 65535          # 监听队列最大长度
      net.core.netdev_max_backlog = 65535 # 网络设备积压
      net.core.rmem_max = 16777216       # 接收缓冲区最大
      net.core.wmem_max = 16777216       # 发送缓冲区最大
      net.core.rmem_default = 262144
      net.core.wmem_default = 262144
      
      # TCP 优化
      net.ipv4.tcp_max_syn_backlog = 65535
      net.ipv4.tcp_tw_reuse = 1          # 允许重用 TIME_WAIT 连接
      net.ipv4.tcp_fin_timeout = 15
      net.ipv4.tcp_keepalive_time = 300
      net.ipv4.tcp_keepalive_probes = 5
      net.ipv4.tcp_keepalive_intvl = 15
      net.ipv4.ip_local_port_range = 1024 65535
      
      # 连接跟踪
      net.netfilter.nf_conntrack_max = 1000000
      
      # 应用修改
      # sudo sysctl -p

      文件描述符限制

      # /etc/security/limits.conf
      nginx  soft  nofile  65535
      nginx  hard  nofile  65535
      nginx  soft  nproc   65535
      nginx  hard  nproc   65535
      
      # 或在 systemd 服务文件中设置
      # [Service]
      # LimitNOFILE=65535
      # LimitNPROC=65535

      Nginx 配置中的关键参数

      # 全局配置
      worker_processes auto;        # 等于 CPU 核心数
      worker_rlimit_nofile 65535;  # 每个 worker 最大文件描述符数
      worker_cpu_affinity auto;     # CPU 亲和性(自动绑定)
      
      # events 块
      events {
          worker_connections 4096;   # 每 worker 最大并发连接
          use epoll;                 # 最佳 I/O 模型
          multi_accept on;           # 批量接受连接
          accept_mutex off;          # 使用 reuseport 时关闭
      }
      
      # http 块
      http {
          sendfile on;               # 零拷贝传输
          tcp_nopush on;             # 合并小数据包
          tcp_nodelay on;            # 禁用 Nagle 算法
          keepalive_timeout 65;      # 长连接超时
          keepalive_requests 1000;   # 单连接最大请求数
      
          # 连接限制
          limit_conn_zone $binary_remote_addr zone=addr:10m;
          limit_req_zone $binary_remote_addr zone=req:10m rate=10r/s;
      }

      7.2 静态文件优化

      Sendfile 与零拷贝

      # 启用 sendfile(内核直接从文件发送数据到网络)
      sendfile on;
      
      # 启用 aio(异步 I/O,适用于大文件)
      aio on;
      directio 512;  # 大于 512 字节的文件使用直接 I/O

      Gzip 压缩优化

      # 在 http 或 server 块中
      gzip on;                    # 启用 gzip
      gzip_vary on;               # 添加 Vary: Accept-Encoding 头
      gzip_proxied any;           # 对所有代理请求压缩
      gzip_comp_level 5;          # 压缩级别 (1-9),5 是较好的平衡
      gzip_min_length 256;        # 最小压缩大小(避免压缩小文件)
      gzip_buffers 16 8k;         # 压缩缓冲区
      
      # 需要压缩的 MIME 类型
      gzip_types
          text/plain
          text/css
          text/javascript
          text/xml
          application/json
          application/javascript
          application/x-javascript
          application/xml
          application/xml+rss
          application/vnd.ms-fontobject
          font/opentype
          image/svg+xml
          image/x-icon;

      浏览器缓存控制

      # 静态资源长缓存
      location ~* \.(jpg|jpeg|png|gif|ico|svg|webp|css|js|woff2?|ttf|eot)$ {
          expires 1y;
          add_header Cache-Control "public, immutable";
          access_log off;
      }
      
      # HTML 文件短缓存
      location ~* \.html?$ {
          expires 1h;
          add_header Cache-Control "public, must-revalidate";
      }
      
      # API 响应不缓存
      location /api/ {
          add_header Cache-Control "no-store, no-cache, must-revalidate";
          add_header Pragma "no-cache";
      }

      Open File Cache

      # 缓存文件元数据(减少 stat 系统调用)
      open_file_cache max=10000 inactive=60s;
      open_file_cache_valid 60s;       # 验证缓存有效性的间隔
      open_file_cache_min_uses 2;      # 文件最少使用次数才缓存
      open_file_cache_errors on;       # 缓存文件错误(404等)

      7.3 限流与流量控制

      连接数限制(limit_conn)

      # 在 http 块中定义区域
      limit_conn_zone $binary_remote_addr zone=addr:10m;
      limit_conn_zone $server_name zone=perserver:10m;
      
      # 在 server/location 中使用
      server {
          # 每个 IP 最多 10 个并发连接
          limit_conn addr 10;
      
          # 每个虚拟主机最多 1000 个并发连接
          limit_conn perserver 1000;
      
          # 超限返回状态码
          limit_conn_status 503;
          limit_conn_log_level warn;
      }

      请求速率限制(limit_req)

      # 在 http 块中定义区域
      # rate=10r/s 表示每秒 10 个请求
      limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
      limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;
      
      # 在 server/location 中使用
      server {
          # API 限流:突发允许 20 个,无延迟处理
          location /api/ {
              limit_req zone=api_limit burst=20 nodelay;
              limit_req_status 429;
              proxy_pass http://api_backend;
          }
      
          # 登录接口更严格的限流
          location /login {
              limit_req zone=login_limit burst=5 nodelay;
              proxy_pass http://auth_backend;
          }
      
          # 白名单排除
          location /admin/ {
              # 不应用限流(通过 geo 模块实现白名单)
              limit_req zone=api_limit burst=100 nodelay;
          }
      }
      
      # 使用 geo 模块创建白名单
      geo $limit_req {
          default 1;
          10.0.0.0/8 0;       # 内网不限流
          192.168.0.0/16 0;   # 内网不限流
      }
      
      # 条件限流
      map $limit_req $limit_key {
          0 "";
          1 $binary_remote_addr;
      }
      
      limit_req_zone $limit_key zone=conditional:10m rate=10r/s;

      八、安全加固

      8.1 安全基础配置

      隐藏版本信息

      http {
          # 隐藏 Nginx 版本号
          server_tokens off;
      
          # 修改 Server 头(需要编译时修改或 More Headers 模块)
          more_set_headers 'Server: MyServer';
      }

      禁止目录遍历和信息泄露

      # 禁止目录列表
      autoindex off;
      
      # 禁止访问隐藏文件
      location ~ /\. {
          deny all;
          access_log off;
          log_not_found off;
      }
      
      # 禁止访问敏感文件
      location ~* \.(env|git|svn|htaccess|htpasswd|ini|log|sh|conf|bak)$ {
          deny all;
      }
      
      # 禁止访问备份文件
      location ~ ~$ {
          deny all;
      }

      访问控制

      # IP 黑白名单
      location /admin/ {
          # 白名单模式
          allow 10.0.0.0/8;
          allow 192.168.1.100;
          deny all;
      
          # 或使用黑名单模式
          # deny 10.10.10.0/24;
          # allow all;
      }
      
      # HTTP Basic 认证
      location /admin/ {
          auth_basic "Admin Area";
          auth_basic_user_file /etc/nginx/.htpasswd;
      
          # 同时限制 IP
          allow 192.168.1.0/24;
          deny all;
          satisfy all;  # 必须同时满足 IP 和认证
      }
      
      # 生成密码文件
      # htpasswd -c /etc/nginx/.htpasswd admin

      安全头配置

      # 全局安全头
      add_header X-Frame-Options "SAMEORIGIN" always;
      add_header X-Content-Type-Options "nosniff" always;
      add_header X-XSS-Protection "1; mode=block" always;
      add_header Referrer-Policy "strict-origin-when-cross-origin" always;
      add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
      add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always;

      8.2 防御常见攻击

      防御 CC 攻击

      # 组合多种限流策略
      http {
          # 正常请求限流
          limit_req_zone $binary_remote_addr zone=normal:10m rate=30r/s;
      
          # 特殊路径更严格
          limit_req_zone $binary_remote_addr zone=strict:10m rate=5r/s;
      
          # 连接数限制
          limit_conn_zone $binary_remote_addr zone=conn:10m;
      
          # 使用 geo 模块封禁恶意 IP
          geo $blocked_ip {
              default 0;
              # 已知恶意 IP 段
              203.0.113.0/24 1;
              198.51.100.0/24 1;
          }
      
          server {
              # 封禁恶意 IP
              if ($blocked_ip) {
                  return 403;
              }
      
              # 连接数限制
              limit_conn conn 50;
      
              # 正常请求限流
              limit_req zone=normal burst=50 nodelay;
      
              # 敏感路径更严格
              location ~* (login|register|search|api) {
                  limit_req zone=strict burst=10 nodelay;
              }
      
              # 检测异常 User-Agent
              if ($http_user_agent ~* (nikto|sqlmap|nmap|masscan|dirbuster)) {
                  return 403;
              }
          }
      }

      防御 SQL 注入和 XSS

      # 在 server 或 location 块中
      # 检测 URL 中的 SQL 注入模式
      if ($query_string ~* "(union.*select|insert.*into|delete.*from|drop.*table|update.*set|benchmark\(|sleep\()" ) {
          return 403;
      }
      
      # 检测常见的 XSS 攻击
      if ($query_string ~* "(<|%3C).*script.*(>|%3E)") {
          return 403;
      }
      
      # 更安全的做法:使用 WAF(如 ModSecurity)
      # 或使用 Nginx 的 njs 模块进行请求过滤

      防御慢速攻击(Slowloris)

      # 设置超时时间
      client_header_timeout 10s;
      client_body_timeout 10s;
      send_timeout 10s;
      
      # 限制请求头大小
      client_header_buffer_size 1k;
      large_client_header_buffers 4 8k;
      
      # 限制请求体大小
      client_max_body_size 10m;
      
      # 连接限制
      keepalive_timeout 15s;
      keepalive_requests 100;

      九、模块系统

      9.1 模块架构与分类

      模块分类

      Nginx 的功能通过模块化实现,主要分为以下几类:

      核心模块(Core)

      提供基础功能,如事件处理、进程管理、配置解析。

      events

      http

      mail

      stream

      事件模块(Event)

      实现不同的 I/O 多路复用机制。

      epoll

      kqueue

      select

      poll

      HTTP 模块

      处理 HTTP 协议相关的各种功能。

      proxy

      gzip

      ssl

      rewrite

      第三方模块

      社区开发的扩展模块,需要编译时加入。

      headers-more

      echo

      lua

      njs

      模块加载方式

      • 静态编译:模块直接编译到 Nginx 二进制文件中
      • 动态加载(Nginx 1.9.11+):使用 load_module 指令动态加载 .so 文件
      # 动态加载模块
      load_module modules/ngx_http_image_filter_module.so;
      load_module modules/ngx_http_geoip_module.so;
      load_module /usr/lib/nginx/modules/ndk_http_module.so;
      load_module /usr/lib/nginx/modules/ngx_http_lua_module.so;

      9.2 常用第三方模块

      Nginx 官方动态模块

      模块名功能
      ngx_http_geoip_module基于 GeoIP 数据库的地理位置识别
      ngx_http_image_filter_module图片实时处理(缩放、裁剪、旋转)
      ngx_http_xslt_moduleXML/XSLT 转换
      ngx_stream_moduleTCP/UDP 四层代理
      ngx_http_perl_module嵌入 Perl 脚本

      社区第三方模块

      模块名功能安装方式
      headers-more-nginx-module修改/添加/删除响应头编译时 --add-module
      echo-nginx-moduleecho、sleep 等调试指令编译时 --add-module
      lua-nginx-module (OpenResty)嵌入 Lua 脚本,实现复杂逻辑OpenResty 或编译
      njs嵌入 JavaScript 脚本动态加载
      ModSecurityWeb 应用防火墙(WAF)动态加载
      brotliBrotli 压缩支持编译时 --add-module
      pagespeed自动优化网页性能编译时 --add-module

      十、高级应用场景

      10.1 TCP/UDP 四层代理(Stream 模块)

      TCP 反向代理

      # 在 nginx.conf 顶层配置(与 http 同级)
      stream {
          # 日志格式
          log_format stream_fmt '$remote_addr [$time_local] '
                                '$protocol $status $bytes_sent $bytes_received '
                                '$session_time "$upstream_addr"';
          access_log /var/log/nginx/stream.log stream_fmt;
      
          # MySQL 代理
          upstream mysql_backend {
              server 10.0.0.1:3306;
              server 10.0.0.2:3306 backup;
          }
      
          server {
              listen 3306;
              proxy_pass mysql_backend;
              proxy_connect_timeout 5s;
              proxy_timeout 300s;
          }
      
          # Redis 代理
          upstream redis_backend {
              hash $remote_addr consistent;
              server 10.0.0.10:6379;
              server 10.0.0.11:6379;
              server 10.0.0.12:6379;
          }
      
          server {
              listen 6379;
              proxy_pass redis_backend;
          }
      
          # SSH 代理
          server {
              listen 2222;
              proxy_pass 10.0.0.5:22;
              proxy_timeout 1h;
          }
      }

      UDP 代理

      stream {
          # DNS 负载均衡
          upstream dns_servers {
              server 8.8.8.8:53;
              server 8.8.4.4:53;
              server 1.1.1.1:53;
          }
      
          server {
              listen 53 udp;
              proxy_pass dns_servers;
              proxy_responses 1;     # 期望的响应包数
              proxy_timeout 5s;
          }
      }

      SNI 路由(基于 TLS SNI 的流量分发)

      stream {
          # 基于 SNI 将流量分发到不同的后端
          map $ssl_preread_server_name $backend {
              example.com      example_backend;
              api.example.com  api_backend;
              default          default_backend;
          }
      
          upstream example_backend {
              server 10.0.0.1:443;
          }
      
          upstream api_backend {
              server 10.0.0.2:443;
          }
      
          upstream default_backend {
              server 10.0.0.3:443;
          }
      
          server {
              listen 443;
              ssl_preread on;    # 预读 TLS 握手获取 SNI
              proxy_pass $backend;
          }
      }

      10.2 微服务网关配置

      API 网关模式

      # 各微服务的 upstream
      upstream user_service {
          server 10.0.1.10:8080;
          server 10.0.1.11:8080;
      }
      
      upstream order_service {
          server 10.0.2.10:8080;
          server 10.0.2.11:8080;
      }
      
      upstream product_service {
          server 10.0.3.10:8080;
          server 10.0.3.11:8080;
      }
      
      upstream auth_service {
          server 10.0.4.10:8080;
      }
      
      # 公共代理配置
      proxy_http_version 1.1;
      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;
      proxy_set_header X-Request-ID $request_id;
      proxy_connect_timeout 5s;
      proxy_read_timeout 30s;
      
      server {
          listen 443 ssl http2;
          server_name api.example.com;
      
          ssl_certificate /path/to/cert.pem;
          ssl_certificate_key /path/to/key.pem;
      
          # 限流
          limit_req zone=api_global burst=100 nodelay;
      
          # 用户服务
          location /api/users {
              proxy_pass http://user_service;
              limit_req zone=api_strict burst=20 nodelay;
          }
      
          # 订单服务
          location /api/orders {
              proxy_pass http://order_service;
              limit_req zone=api_strict burst=20 nodelay;
          }
      
          # 商品服务
          location /api/products {
              proxy_pass http://product_service;
          }
      
          # 认证服务
          location /api/auth {
              proxy_pass http://auth_service;
              limit_req zone=login_limit burst=5 nodelay;
          }
      
          # 健康检查端点
          location /health {
              access_log off;
              return 200 "OK\n";
              add_header Content-Type text/plain;
          }
      }

      A/B 测试配置

      # 使用 split_clients 模块实现流量分割
      split_clients "${remote_addr}" $ab_version {
          50%  "version_a";
          *    "version_b";
      }
      
      upstream app_a {
          server 10.0.0.1:8080;
      }
      
      upstream app_b {
          server 10.0.0.2:8080;
      }
      
      server {
          listen 80;
          server_name app.example.com;
      
          location / {
              if ($ab_version = "version_a") {
                  proxy_pass http://app_a;
              }
              if ($ab_version = "version_b") {
                  proxy_pass http://app_b;
              }
      
              # 添加标记头用于日志分析
              add_header X-AB-Version $ab_version;
          }
      }

      10.3 高可用与蓝绿部署

      蓝绿部署

      # 定义蓝色和绿色环境
      upstream app_blue {
          server 10.0.0.1:8080;
          server 10.0.0.2:8080;
      }
      
      upstream app_green {
          server 10.0.0.3:8080;
          server 10.0.0.4:8080;
      }
      
      # 使用 map 或 geo 控制流量方向
      map $cookie_deploy_version $backend {
          default     "app_blue";
          "green"     "app_green";
      }
      
      # 或者通过请求头控制(便于测试)
      server {
          listen 80;
      
          location / {
              # 检查请求头
              if ($http_x_deploy_version = "green") {
                  proxy_pass http://app_green;
                  break;
              }
      
              # 默认使用蓝色环境
              proxy_pass http://app_blue;
          }
      }
      
      # 切换流量:修改 map 中的 default 值,然后 reload
      # map $cookie_deploy_version $backend {
      #     default     "app_green";   ← 改为绿色
      #     "blue"      "app_blue";
      # }

      金丝雀发布(Canary Release)

      # 将小比例流量导入新版本
      split_clients "${request_id}" $canary {
          5%   "canary";     # 5% 流量到新版本
          *    "stable";     # 95% 流量到稳定版
      }
      
      upstream stable_backend {
          server 10.0.0.1:8080;
          server 10.0.0.2:8080;
      }
      
      upstream canary_backend {
          server 10.0.0.3:8080;  # 新版本
      }
      
      server {
          listen 80;
      
          location / {
              if ($canary = "canary") {
                  proxy_pass http://canary_backend;
                  break;
              }
              proxy_pass http://stable_backend;
          }
      }

      10.4 Nginx 与 Docker/Kubernetes 集成

      Kubernetes Ingress Controller

      # Kubernetes Ingress 资源示例
      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: app-ingress
        annotations:
          nginx.ingress.kubernetes.io/rewrite-target: /
          nginx.ingress.kubernetes.io/ssl-redirect: "true"
          nginx.ingress.kubernetes.io/proxy-body-size: "50m"
          nginx.ingress.kubernetes.io/rate-limit: "10"
          nginx.ingress.kubernetes.io/rate-limit-window: "1m"
      spec:
        ingressClassName: nginx
        tls:
        - hosts:
          - app.example.com
          secretName: app-tls
        rules:
        - host: app.example.com
          http:
            paths:
            - path: /api
              pathType: Prefix
              backend:
                service:
                  name: api-service
                  port:
                    number: 8080
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: frontend-service
                  port:
                    number: 80

      Docker 动态配置(模板化)

      # 使用 envsubst 动态生成配置
      # nginx.template
      server {
          listen ${LISTEN_PORT:-80};
          server_name ${SERVER_NAME:-localhost};
      
          location / {
              proxy_pass http://${BACKEND_HOST:-backend}:${BACKEND_PORT:-8080};
          }
      }
      
      # Dockerfile
      FROM nginx:alpine
      COPY nginx.template /etc/nginx/templates/default.conf.template
      ENV LISTEN_PORT=80
      ENV SERVER_NAME=example.com
      ENV BACKEND_HOST=backend
      ENV BACKEND_PORT=8080
      
      # docker-compose.yml 中使用
      # environment:
      #   - SERVER_NAME=example.com
      #   - BACKEND_HOST=app
      #   - BACKEND_PORT=3000

      十一、故障排查

      11.1 常用诊断命令

      基本检查

      # 测试配置文件语法
      nginx -t
      nginx -T  # 测试并输出完整配置
      
      # 查看 Nginx 进程
      ps aux | grep nginx
      
      # 查看端口占用
      ss -tlnp | grep nginx
      # 或
      netstat -tlnp | grep nginx
      
      # 查看 Nginx 编译参数
      nginx -V
      
      # 查看连接状态
      ss -s
      
      # 查看当前连接数
      ss -tn state established | wc -l
      
      # 查看各状态连接数
      ss -tn | awk '{print $1}' | sort | uniq -c | sort -rn

      日志分析

      # 实时查看访问日志
      tail -f /var/log/nginx/access.log
      
      # 实时查看错误日志
      tail -f /var/log/nginx/error.log
      
      # 分析访问最多的 IP
      awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
      
      # 分析访问最多的 URL
      awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
      
      # 分析 HTTP 状态码分布
      awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
      
      # 分析请求方法分布
      awk '{print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
      
      # 查看带宽使用
      awk '{sum+=$10} END {print sum/1024/1024 " MB"}' /var/log/nginx/access.log

      性能诊断

      # 查看 worker 进程资源使用
      top -p $(pgrep -d, nginx)
      
      # 查看文件描述符使用
      ls -la /proc/$(pgrep -o nginx)/fd | wc -l
      
      # 使用 strace 跟踪系统调用
      strace -p  -c
      
      # 使用 perf 分析性能瓶颈
      perf record -g -p 
      perf report

      11.2 常见错误及解决方案

      错误代码速查表

      错误原因解决方案
      502 Bad Gateway后端服务不可用或响应超时检查后端服务状态、端口、防火墙
      504 Gateway Timeout后端响应超时增大 proxy_read_timeout,优化后端性能
      413 Request Entity Too Large请求体超过限制增大 client_max_body_size
      403 Forbidden权限不足或被 deny 规则拦截检查文件权限、allow/deny 规则
      429 Too Many Requests触发限流调整 limit_req/limit_conn 配置

      常见问题排查

      问题:Worker 进程异常退出

      # 检查错误日志
      tail -100 /var/log/nginx/error.log
      
      # 检查系统日志
      journalctl -u nginx --since "1 hour ago"
      dmesg | grep -i oom  # 检查 OOM Killer

      问题:worker_connections are not enough

      # 增加 worker_connections
      events {
          worker_connections 8192;
      }
      
      # 同时确保系统文件描述符足够
      worker_rlimit_nofile 16384;

      问题:upstream timed out

      # 增加超时时间
      proxy_connect_timeout 30s;
      proxy_send_timeout 60s;
      proxy_read_timeout 60s;
      
      # 检查后端服务是否健康
      curl -I http://backend_server:port/health

      问题:SSL 证书错误

      # 检查证书有效期
      openssl x509 -in /etc/nginx/ssl/cert.pem -noout -dates
      
      # 检查证书链完整性
      openssl verify -CAfile /etc/nginx/ssl/chain.pem /etc/nginx/ssl/cert.pem
      
      # 测试 SSL 配置
      openssl s_client -connect example.com:443 -servername example.com

      11.3 监控与告警

      启用 Stub Status 模块

      server {
          listen 8080;
          server_name localhost;
      
          location /nginx_status {
              stub_status on;
              access_log off;
      
              # 限制访问
              allow 127.0.0.1;
              allow 10.0.0.0/8;
              deny all;
          }
      }
      
      # 输出示例:
      # Active connections: 291
      # server accepts handled requests
      #  16630948 16630948 31070465
      # Reading: 6 Writing: 179 Waiting: 106

      Prometheus 监控(使用 nginx-prometheus-exporter)

      # Docker 运行 exporter
      docker run -p 9113:9113 \
          nginx/nginx-prometheus-exporter:latest \
          --nginx.scrape-uri=http://nginx:8080/nginx_status
      
      # 或使用 Nginx Plus 原生支持 Prometheus
      # location /api/ {
      #     api write=on;  # Nginx Plus API
      # }

      关键监控指标

      • 连接数:活跃连接数、等待连接数
      • 请求数:QPS、请求成功率
      • 状态码分布:2xx/3xx/4xx/5xx 比例
      • 响应时间:平均响应时间、P95/P99 延迟
      • 带宽使用:入站/出站流量
      • 错误率:5xx 错误比例
      • 上游健康:后端服务器健康状态

      十二、最佳实践

      12.1 配置文件组织规范

      推荐目录结构

      /etc/nginx/
      ├── nginx.conf              # 主配置文件
      ├── mime.types              # MIME 类型映射
      ├── conf.d/                 # 通用配置片段
      │   ├── gzip.conf
      │   ├── security.conf
      │   └── logging.conf
      ├── sites-available/        # 所有站点配置(激活/未激活)
      │   ├── example.com.conf
      │   ├── api.example.com.conf
      │   └── admin.example.com.conf
      ├── sites-enabled/          # 已激活的站点(软链接)
      │   ├── example.com.conf -> ../sites-available/example.com.conf
      │   └── api.example.com.conf -> ../sites-available/api.example.com.conf
      ├── upstreams/              # upstream 定义
      │   ├── backend.conf
      │   └── websocket.conf
      ├── ssl/                    # SSL 证书和密钥
      │   ├── example.com.crt
      │   ├── example.com.key
      │   └── dhparam.pem
      ├── snippets/               # 可复用的配置片段
      │   ├── ssl-params.conf
      │   └── proxy-params.conf
      └── maps/                   # map 定义
          └── geo-blocking.conf

      配置片段复用

      # /etc/nginx/snippets/ssl-params.conf
      ssl_protocols TLSv1.2 TLSv1.3;
      ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
      ssl_prefer_server_ciphers off;
      ssl_session_cache shared:SSL:10m;
      ssl_session_timeout 1d;
      ssl_session_tickets off;
      ssl_stapling on;
      ssl_stapling_verify on;
      
      # /etc/nginx/snippets/proxy-params.conf
      proxy_http_version 1.1;
      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;
      proxy_set_header Connection "";
      
      # 在站点配置中引用
      server {
          listen 443 ssl http2;
          server_name example.com;
      
          ssl_certificate /etc/nginx/ssl/example.com.crt;
          ssl_certificate_key /etc/nginx/ssl/example.com.key;
          include snippets/ssl-params.conf;
      
          location / {
              proxy_pass http://backend;
              include snippets/proxy-params.conf;
          }
      }

      12.2 运维自动化

      平滑重载配置

      # 测试配置后重载(推荐)
      sudo nginx -t && sudo nginx -s reload
      
      # 或
      sudo systemctl reload nginx

      零停机升级(Hot Upgrade)

      #!/bin/bash
      # Nginx 零停机升级脚本
      
      OLD_PID=$(cat /run/nginx.pid)
      
      # 1. 用新的二进制文件启动新的 master 进程
      kill -USR2 $OLD_PID
      
      # 2. 等待新的 master 进程创建 PID 文件
      sleep 1
      NEW_PID=$(cat /run/nginx.pid)
      
      # 3. 让旧 master 进程优雅退出 worker
      kill -WINCH $OLD_PID
      
      # 4. 确认新进程工作正常后,让旧 master 退出
      # kill -QUIT $OLD_PID
      
      # 如果需要回滚:
      # kill -HUP $OLD_PID   # 重新启动旧 worker
      # kill -QUIT $NEW_PID  # 关闭新 master

      自动化备份与部署脚本

      #!/bin/bash
      # Nginx 配置部署脚本
      
      NGINX_DIR="/etc/nginx"
      BACKUP_DIR="/backup/nginx"
      DATE=$(date +%Y%m%d_%H%M%S)
      
      # 创建备份
      mkdir -p $BACKUP_DIR
      cp -r $NGINX_DIR $BACKUP_DIR/nginx_backup_$DATE
      
      # 同步新配置(从 Git 仓库)
      cd /path/to/nginx-config-repo
      git pull origin main
      
      # 复制配置到 Nginx 目录
      cp -r ./nginx/* $NGINX_DIR/
      
      # 测试配置
      if nginx -t 2>&1 | grep -q "syntax is ok"; then
          echo "配置测试通过,正在重载..."
          nginx -s reload
          echo "部署成功!"
      else
          echo "配置测试失败,正在回滚..."
          rm -rf $NGINX_DIR
          cp -r $BACKUP_DIR/nginx_backup_$DATE $NGINX_DIR
          echo "已回滚到上一版本"
          exit 1
      fi

      Ansible 自动化管理

      ---
      # Ansible Playbook: nginx-deploy.yml
      - hosts: webservers
        become: yes
        tasks:
          - name: Copy nginx configuration
            template:
              src: nginx.conf.j2
              dest: /etc/nginx/nginx.conf
              validate: 'nginx -t -c %s'
            notify: reload nginx
      
          - name: Copy site configurations
            template:
              src: "sites/{{ item }}.conf.j2"
              dest: "/etc/nginx/sites-available/{{ item }}.conf"
            loop: "{{ nginx_sites }}"
            notify: reload nginx
      
          - name: Enable sites
            file:
              src: "/etc/nginx/sites-available/{{ item }}.conf"
              dest: "/etc/nginx/sites-enabled/{{ item }}.conf"
              state: link
            loop: "{{ nginx_enabled_sites }}"
            notify: reload nginx
      
        handlers:
          - name: reload nginx
            service:
              name: nginx
              state: reloaded

      12.3 完整生产环境配置模板

      生产环境完整 nginx.conf

      # ===== 全局配置 =====
      user nginx;
      worker_processes auto;
      worker_rlimit_nofile 65535;
      worker_cpu_affinity auto;
      error_log /var/log/nginx/error.log warn;
      pid /run/nginx.pid;
      
      # ===== 事件配置 =====
      events {
          worker_connections 4096;
          use epoll;
          multi_accept on;
          accept_mutex off;
      }
      
      # ===== HTTP 配置 =====
      http {
          # --- 基本设置 ---
          include /etc/nginx/mime.types;
          default_type application/octet-stream;
          server_tokens off;
          sendfile on;
          tcp_nopush on;
          tcp_nodelay on;
          keepalive_timeout 65;
          keepalive_requests 1000;
          client_max_body_size 50m;
          types_hash_max_size 2048;
          server_names_hash_bucket_size 128;
      
          # --- 日志配置 ---
          log_format main '$remote_addr - $remote_user [$time_local] '
                          '"$request" $status $body_bytes_sent '
                          '"$http_referer" "$http_user_agent" '
                          '"$http_x_forwarded_for" '
                          'rt=$request_time';
      
          access_log /var/log/nginx/access.log main buffer=16k flush=5s;
      
          # --- 压缩配置 ---
          gzip on;
          gzip_vary on;
          gzip_proxied any;
          gzip_comp_level 5;
          gzip_min_length 256;
          gzip_types text/plain text/css application/json
                     application/javascript text/xml
                     application/xml application/xml+rss
                     text/javascript image/svg+xml;
      
          # --- 限流配置 ---
          limit_req_zone $binary_remote_addr zone=general:10m rate=30r/s;
          limit_req_zone $binary_remote_addr zone=api:10m rate=20r/s;
          limit_req_zone $binary_remote_addr zone=login:10m rate=5r/s;
          limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
      
          # --- 文件缓存 ---
          open_file_cache max=10000 inactive=60s;
          open_file_cache_valid 60s;
          open_file_cache_min_uses 2;
          open_file_cache_errors on;
      
          # --- 代理缓存路径 ---
          proxy_cache_path /var/cache/nginx/proxy levels=1:2
              keys_zone=static_cache:10m max_size=10g inactive=1d
              use_temp_path=off;
      
          # --- 上游服务器定义 ---
          include /etc/nginx/upstreams/*.conf;
      
          # --- 站点配置 ---
          include /etc/nginx/conf.d/*.conf;
          include /etc/nginx/sites-enabled/*.conf;
      }

      生产站点配置示例

      # /etc/nginx/sites-available/example.com.conf
      
      # HTTP -> HTTPS 重定向
      server {
          listen 80;
          listen [::]:80;
          server_name example.com www.example.com;
          return 301 https://$host$request_uri;
      }
      
      # HTTPS 主站
      server {
          listen 443 ssl http2;
          listen [::]:443 ssl http2;
      
          server_name example.com www.example.com;
      
          # SSL 配置
          ssl_certificate /etc/nginx/ssl/example.com/fullchain.pem;
          ssl_certificate_key /etc/nginx/ssl/example.com/privkey.pem;
          include snippets/ssl-params.conf;
      
          # 根目录
          root /var/www/example.com/html;
          index index.html;
      
          # 安全头
          add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
          add_header X-Frame-Options "SAMEORIGIN" always;
          add_header X-Content-Type-Options "nosniff" always;
          add_header Referrer-Policy "strict-origin-when-cross-origin" always;
      
          # 限流
          limit_req zone=general burst=50 nodelay;
          limit_conn conn_limit 100;
      
          # 静态文件
          location ~* \.(jpg|jpeg|png|gif|ico|svg|webp|css|js|woff2?|ttf|eot)$ {
              expires 1y;
              add_header Cache-Control "public, immutable";
              access_log off;
          }
      
          # HTML 文件
          location ~* \.html?$ {
              expires 1h;
              add_header Cache-Control "public, must-revalidate";
          }
      
          # API 代理
          location /api/ {
              limit_req zone=api burst=30 nodelay;
              proxy_pass http://api_backend;
              include snippets/proxy-params.conf;
          }
      
          # 默认路由
          location / {
              try_files $uri $uri/ /index.html;
          }
      
          # 健康检查
          location = /health {
              access_log off;
              return 200 "OK\n";
              add_header Content-Type text/plain;
          }
      
          # 禁止访问隐藏文件
          location ~ /\. {
              deny all;
              access_log off;
              log_not_found off;
          }
      }
      
      # www 重定向到非 www
      server {
          listen 443 ssl http2;
          server_name www.example.com;
          ssl_certificate /etc/nginx/ssl/example.com/fullchain.pem;
          ssl_certificate_key /etc/nginx/ssl/example.com/privkey.pem;
          return 301 https://example.com$request_uri;
      }

      12.4 Nginx 与主流技术栈集成

      Nginx + Node.js

      upstream nodejs_app {
          server 127.0.0.1:3000;
          keepalive 32;
      }
      
      server {
          listen 80;
          server_name nodeapp.example.com;
      
          location / {
              proxy_pass http://nodejs_app;
              proxy_http_version 1.1;
              proxy_set_header Connection "";
              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 支持
          location /socket.io/ {
              proxy_pass http://nodejs_app;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection "upgrade";
          }
      }

      Nginx + Python (Gunicorn/uWSGI)

      # Gunicorn
      upstream gunicorn_app {
          server unix:/run/gunicorn.sock;
          # 或: server 127.0.0.1:8000;
      }
      
      server {
          listen 80;
          server_name python-app.example.com;
      
          location / {
              proxy_pass http://gunicorn_app;
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
          }
      
          # Django 静态文件
          location /static/ {
              alias /var/www/python-app/static/;
              expires 30d;
          }
      }
      
      # uWSGI
      server {
          listen 80;
          server_name uwsgi-app.example.com;
      
          location / {
              uwsgi_pass unix:///run/uwsgi.sock;
              # 或: uwsgi_pass 127.0.0.1:3031;
              include uwsgi_params;
              uwsgi_param Host $host;
              uwsgi_param X-Real-IP $remote_addr;
          }
      }

      Nginx + PHP (PHP-FPM)

      server {
          listen 80;
          server_name php-app.example.com;
          root /var/www/php-app/public;
          index index.php index.html;
      
          location / {
              try_files $uri $uri/ /index.php?$query_string;
          }
      
          location ~ \.php$ {
              fastcgi_pass unix:/run/php/php8.2-fpm.sock;
              # 或: fastcgi_pass 127.0.0.1:9000;
              fastcgi_index index.php;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              include fastcgi_params;
      
              # 性能优化
              fastcgi_buffer_size 32k;
              fastcgi_buffers 16 16k;
              fastcgi_busy_buffers_size 32k;
          }
      
          # Laravel 特定
          location ~ /\.(?!well-known).* {
              deny all;
          }
      }

      45.64.74.193

← 返回IT 技术 yicool 百科 · 🚀 Nginx 软件设计架构与详细教程

评论 0