Nginx 知识体系 · 上篇:基础与核心


第一章 基础概念

1.1 Nginx 是什么

Nginx(engine-x)是一款高性能 HTTP/反向代理/负载均衡 服务器,由 Igor Sysoev 于 2004 年发布,专为解决 C10K 问题(单机万级并发)而设计。

核心特征:高并发、低内存(~2.5KB/连接)、事件驱动、模块化、热部署、跨平台。

1.2 核心功能

功能 说明 典型场景
Web Server 高效提供静态资源(HTML/CSS/JS/图片) 静态站点托管
Reverse Proxy 隐藏后端服务,统一入口 API 转发
Load Balancer 将请求按策略分发到多台后端 水平扩展
Gateway API 路由、认证鉴权、限流 微服务网关

正向代理 vs 反向代理

  • 正向代理:代理客户端(如 VPN),客户端知道代理存在
  • 反向代理:代理服务端(如 Nginx),客户端不知道后端存在

1.3 工作模型

Master / Worker 多进程架构

复制代码
Master 进程(管理者)
├── 读取/验证配置、绑定端口、管理 Worker
├── 不处理客户端请求
│
├── Worker #1 ── 处理请求(竞争 accept 连接)
├── Worker #2 ── 处理请求
├── Worker #3 ── 处理请求
└── Worker #4 ── 处理请求
nginx 复制代码
worker_processes auto;       # 推荐设为 CPU 核心数
worker_cpu_affinity auto;    # 绑定 Worker 到 CPU

事件驱动模型(epoll)

传统模型:1连接 = 1线程,资源消耗大。

Nginx:单 Worker 通过 epoll/kqueue 事件循环处理数千连接,异步非阻塞。

机制 最大连接数 效率 平台
select 1024 O(n) 全平台
poll 无限制 O(n) Linux
epoll 无限制 O(1) Linux 2.6+
kqueue 无限制 O(1) FreeBSD/macOS
nginx 复制代码
events {
    use epoll;
    worker_connections 65535;
    multi_accept on;
}

第二章 安装与环境

2.1 Linux 安装

bash 复制代码
# Ubuntu / Debian
sudo apt update && sudo apt install -y nginx

# CentOS / RHEL
sudo yum install -y epel-release && sudo yum install -y nginx

# 源码编译安装(自定义模块)
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -zxvf nginx-1.24.0.tar.gz && cd nginx-1.24.0
./configure --prefix=/usr/local/nginx \
    --with-http_ssl_module \
    --with-http_v2_module \
    --with-http_gzip_static_module
make && sudo make install

2.2 Windows / Mac 安装

bash 复制代码
# macOS
brew install nginx

# Windows:下载官方 zip 解压后运行 nginx.exe

2.3 目录结构

复制代码
/etc/nginx/                 # 主配置目录
├── nginx.conf              # 主配置文件
├── conf.d/                 # 自定义配置(推荐)
│   └── default.conf
├── sites-available/        # 可用站点(Debian系)
├── sites-enabled/          # 已启用站点(软链接)
├── mime.types              # MIME 类型映射
└── fastcgi_params          # FastCGI 参数

/var/log/nginx/             # 日志目录
├── access.log
└── error.log

/usr/share/nginx/html/      # 默认静态资源目录

2.4 常用命令

bash 复制代码
nginx -t                    # 测试配置语法
nginx -T                    # 测试并输出完整配置
nginx -s reload             # 平滑重载配置(不断开连接)
nginx -s stop               # 快速停止
nginx -s quit               # 优雅退出(处理完当前请求)
nginx -V                    # 查看编译参数和版本
systemctl start nginx       # 启动
systemctl enable nginx      # 开机自启

⚠️ 修改配置后务必先 nginx -t 验证语法,再 nginx -s reload


第三章 配置体系

3.1 配置文件总体结构

nginx 复制代码
# ─── main 全局块 ───
user  nginx;                          # 运行用户
worker_processes  auto;               # Worker 进程数
error_log  /var/log/nginx/error.log;  # 错误日志
pid        /run/nginx.pid;            # PID 文件

# ─── events 块 ───
events {
    worker_connections  1024;         # 单 Worker 最大连接数
    use epoll;
}

# ─── http 块 ───
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile      on;
    keepalive_timeout  65;

    # ─── server 块(虚拟主机)───
    server {
        listen       80;
        server_name  example.com;

        # ─── location 块(路由匹配)───
        location / {
            root   /var/www/html;
            index  index.html;
        }
    }
}

层级关系main → events / http → server → location

3.2 server 块(虚拟主机)

一个 Nginx 可以运行多个网站,每个 server 块定义一个虚拟主机:

nginx 复制代码
# 基于域名的虚拟主机
server {
    listen 80;
    server_name www.site-a.com;
    root /var/www/site-a;
}

server {
    listen 80;
    server_name www.site-b.com;
    root /var/www/site-b;
}

# 基于端口的虚拟主机
server {
    listen 8081;
    root /var/www/app1;
}

匹配优先级 :精确匹配 → 左通配符*.example.com → 右通配符mail.* → 正则 → default_server

3.3 location 块

详见第四章。

3.4 配置拆分(include)

nginx 复制代码
# 主配置文件引入子配置
http {
    include /etc/nginx/conf.d/*.conf;       # 引入所有 .conf
    include /etc/nginx/sites-enabled/*;     # 引入已启用站点
}

最佳实践 :每个站点独立一个配置文件,放在 conf.d/ 目录下。


第四章 路由与匹配规则

4.1 location 匹配类型

修饰符 含义 示例
= 精确匹配 location = /login { }
/ 前缀匹配 location /api/ { }
^~ 前缀匹配(优先级高,匹配后不再正则) location ^~ /static/ { }
~ 正则匹配(区分大小写) location ~ \.php$ { }
~* 正则匹配(不区分大小写) `location ~* .(jpg

4.2 匹配优先级(从高到低)

复制代码
1. = 精确匹配           → 命中立即停止
2. ^~ 前缀匹配          → 命中不再正则
3. ~ / ~* 正则匹配      → 按配置顺序,第一个命中即停止
4. / 普通前缀匹配       → 选最长匹配

完整示例

nginx 复制代码
server {
    # 1️⃣ 精确匹配:只匹配 /
    location = / {
        return 200 "exact root";
    }

    # 2️⃣ 优先前缀:/static/ 开头的不再走正则
    location ^~ /static/ {
        root /var/www;
    }

    # 3️⃣ 正则匹配:.php 结尾
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
    }

    # 4️⃣ 不区分大小写正则:图片文件
    location ~* \.(jpg|jpeg|png|gif|ico)$ {
        expires 30d;
    }

    # 5️⃣ 通用前缀:兜底
    location / {
        proxy_pass http://backend;
    }
}

4.3 URI 处理规则

nginx 复制代码
# proxy_pass 带不带尾部斜杠的区别(重要!)

# 请求 /api/user → 转发到 http://backend/api/user
location /api/ {
    proxy_pass http://backend;          # 不带 URI 部分
}

# 请求 /api/user → 转发到 http://backend/user(去掉 /api 前缀)
location /api/ {
    proxy_pass http://backend/;         # 带尾部斜杠
}

⚠️ 经典坑proxy_pass 后面带不带 / 行为完全不同!带 / 会替换匹配的 location 前缀。


第五章 核心功能模块

5.1 静态资源服务

nginx 复制代码
server {
    listen 80;
    server_name static.example.com;
    root /var/www/static;

    # 目录浏览(可选)
    location /files/ {
        autoindex on;
        autoindex_exact_size off;    # 显示人类可读大小
        autoindex_localtime on;
    }

    # 静态资源缓存
    location ~* \.(css|js|jpg|png|gif|ico|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
        access_log off;              # 静态资源不记日志
    }

    # 404 回退(SPA 应用必须)
    location / {
        try_files $uri $uri/ /index.html;
    }
}

5.2 反向代理

nginx 复制代码
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;

        # ── 必须设置的 Header ──
        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_connect_timeout 10s;      # 连接后端超时
        proxy_read_timeout    60s;      # 等待后端响应超时
        proxy_send_timeout    30s;      # 发送到后端超时

        # ── 缓冲区 ──
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 16k;
    }
}

5.3 负载均衡

nginx 复制代码
# 定义后端集群
upstream backend {
    # 算法选择(四选一)
    # (默认)轮询:依次分配
    # least_conn;                     # 最少连接
    # ip_hash;                        # IP 哈希(会话保持)
    # hash $request_uri consistent;   # 一致性哈希

    server 10.0.0.1:8080 weight=5;                  # 权重
    server 10.0.0.2:8080 weight=3;
    server 10.0.0.3:8080 weight=2 max_fails=3 fail_timeout=30s;
    server 10.0.0.4:8080 backup;                    # 备份节点
    server 10.0.0.5:8080 down;                      # 标记下线
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
        proxy_next_upstream error timeout http_502 http_503;  # 失败重试
    }
}

四种算法对比

算法 特点 适用场景
轮询 默认,均匀分配 后端性能一致
weight 按权重分配 后端性能不一致
ip_hash 同 IP 固定后端 需要会话保持
least_conn 分给连接最少的 请求处理时间差异大

5.4 HTTPS 配置

nginx 复制代码
server {
    listen 443 ssl http2;
    server_name www.example.com;

    # ── 证书配置 ──
    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    # ── SSL 安全参数 ──
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # HSTS(强制 HTTPS)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}

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

Let's Encrypt 免费证书申请

bash 复制代码
# 安装 certbot
sudo apt install certbot python3-certbot-nginx

# 自动申请并配置
sudo certbot --nginx -d www.example.com

# 自动续期
sudo certbot renew --dry-run

5.5 URL 重写

nginx 复制代码
# rewrite 语法:rewrite regex replacement [flag];
# flag: last | break | redirect(302) | permanent(301)

server {
    # 旧路径永久重定向
    rewrite ^/old-page$ /new-page permanent;

    # 去掉 .html 后缀
    rewrite ^(.*)\.html$ $1 permanent;

    # 强制带 www
    if ($host = 'example.com') {
        rewrite ^(.*)$ https://www.example.com$1 permanent;
    }

    # return 更简洁(推荐用于简单跳转)
    location = /github {
        return 302 https://github.com/your-repo;
    }
}

第六章 高级功能

6.1 限流(limit_req)

nginx 复制代码
http {
    # 定义限流区域:每个 IP 每秒 10 个请求
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

    server {
        location /api/ {
            # burst=20:允许突发 20 个排队
            # nodelay:突发请求不延迟处理
            limit_req zone=api_limit burst=20 nodelay;
            limit_req_status 429;           # 超限返回 429
        }
    }
}

6.2 并发连接限制(limit_conn)

nginx 复制代码
http {
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;

    server {
        location /download/ {
            limit_conn conn_limit 5;        # 每 IP 最多 5 个并发连接
            limit_rate 500k;                # 每连接限速 500KB/s
        }
    }
}

6.3 IP 访问控制

nginx 复制代码
# 黑名单模式
location /admin/ {
    deny  192.168.1.100;         # 拒绝特定 IP
    deny  10.0.0.0/8;           # 拒绝网段
    allow all;                   # 其他放行
}

# 白名单模式(推荐用于管理后台)
location /admin/ {
    allow 192.168.1.0/24;        # 只允许内网
    allow 10.0.0.50;
    deny  all;                   # 拒绝其他
}

6.4 防盗链

nginx 复制代码
location ~* \.(jpg|png|gif|mp4)$ {
    valid_referers none blocked server_names *.example.com;
    if ($invalid_referer) {
        return 403;
        # 或返回防盗链提示图
        # rewrite ^/ /images/hotlink-denied.png break;
    }
}

6.5 跨域配置(CORS)

nginx 复制代码
location /api/ {
    # 允许的源(生产环境指定具体域名)
    add_header Access-Control-Allow-Origin $http_origin always;
    add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
    add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-Requested-With" always;
    add_header Access-Control-Allow-Credentials true always;
    add_header Access-Control-Max-Age 3600 always;

    # 预检请求快速返回
    if ($request_method = OPTIONS) {
        return 204;
    }

    proxy_pass http://backend;
}

6.6 WebSocket 支持

nginx 复制代码
location /ws/ {
    proxy_pass http://websocket_backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_read_timeout 3600s;               # WebSocket 长连接超时
}

6.7 文件上传限制

nginx 复制代码
http {
    client_max_body_size 50m;               # 全局上传大小限制

    server {
        location /upload/ {
            client_max_body_size 200m;      # 上传接口单独放大
            client_body_timeout 120s;
            proxy_pass http://upload_backend;
        }
    }
}

第七章 日志与监控

7.1 access_log

nginx 复制代码
http {
    # 日志格式定义
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '$request_time $upstream_response_time';

    # JSON 格式(便于 ELK 采集)
    log_format json_log escape=json
        '{"time":"$time_iso8601",'
         '"ip":"$remote_addr",'
         '"method":"$request_method",'
         '"uri":"$request_uri",'
         '"status":$status,'
         '"size":$body_bytes_sent,'
         '"referer":"$http_referer",'
         '"ua":"$http_user_agent",'
         '"rt":$request_time,'
         '"upstream_rt":"$upstream_response_time"}';

    access_log /var/log/nginx/access.log main;

    server {
        # 按站点分开日志
        access_log /var/log/nginx/site-a.access.log json_log;

        # 静态资源不记日志
        location ~* \.(css|js|ico)$ {
            access_log off;
        }
    }
}

7.2 error_log

nginx 复制代码
# 级别:debug | info | notice | warn | error | crit | alert | emerg
error_log /var/log/nginx/error.log warn;

# 调试特定 IP 的请求
events {
    debug_connection 192.168.1.100;
}

7.3 日志切割

bash 复制代码
# logrotate 配置 /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily
    rotate 30
    missingok
    compress
    delaycompress
    notifempty
    sharedscripts
    postrotate
        [ -f /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid)
    endscript
}

7.4 监控方案

nginx 复制代码
# 开启 stub_status 模块(基础监控)
location /nginx_status {
    stub_status on;
    allow 127.0.0.1;
    deny all;
}
# 输出示例:
# Active connections: 291
# server accepts handled requests
#  16630948 16630948 31070465
# Reading: 6 Writing: 179 Waiting: 106

Prometheus + Grafana 方案 :使用 nginx-prometheus-exporter 采集 stub_status 指标,接入 Grafana 仪表盘。


第八章 性能优化

8.1 Worker 优化

nginx 复制代码
worker_processes auto;                      # CPU 核心数
worker_cpu_affinity auto;                   # CPU 亲和性绑定
worker_rlimit_nofile 65535;                 # 文件描述符上限
worker_priority -10;                        # 提高进程优先级

8.2 连接优化

nginx 复制代码
events {
    worker_connections 65535;
    multi_accept on;
    use epoll;
}

8.3 keepalive

nginx 复制代码
http {
    keepalive_timeout 65;                   # 客户端 keep-alive
    keepalive_requests 1000;                # 单连接最大请求数

    upstream backend {
        server 10.0.0.1:8080;
        keepalive 32;                       # 到后端的连接池大小
    }

    server {
        location / {
            proxy_pass http://backend;
            proxy_http_version 1.1;
            proxy_set_header Connection "";  # 必须清空才能复用
        }
    }
}

8.4 gzip 压缩

nginx 复制代码
http {
    gzip on;
    gzip_vary on;
    gzip_min_length 1k;                     # 小于 1KB 不压缩
    gzip_comp_level 4;                      # 压缩级别(1-9,4为平衡点)
    gzip_types text/plain text/css text/javascript
               application/json application/javascript
               application/xml image/svg+xml;
    gzip_proxied any;
    gzip_disable "MSIE [1-6]\.";

    # 预压缩(推荐配合构建工具)
    gzip_static on;                         # 优先使用 .gz 预压缩文件
}

8.5 静态缓存

nginx 复制代码
# open_file_cache:缓存文件元信息(fd/size/mtime)
open_file_cache max=10000 inactive=60s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

8.6 sendfile / tcp 优化

nginx 复制代码
http {
    sendfile on;                            # 零拷贝传输文件
    tcp_nopush on;                          # 数据包合并(配合 sendfile)
    tcp_nodelay on;                         # 小包立即发送(keep-alive时)
}

性能优化检查清单

优化项 配置 效果
Worker 数量 auto 匹配 CPU 核心
连接上限 65535 支撑高并发
keepalive 开启 减少 TCP 握手
gzip level=4 减少 60-80% 传输量
sendfile on 零拷贝,CPU 占用降低
open_file_cache 开启 减少磁盘 I/O
相关推荐
乘云数字DATABUFF11 小时前
5分钟部署开源APM Databuff:OpenTelemetry全链路追踪入门实战
运维·后端
荣--2 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森2 天前
动手实战学 Docker — 从零到集群编排完全指南
运维
Avan_菜菜3 天前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
SelectDB4 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode5 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220706 天前
如何搭建本地yum源(上)
运维
ping某7 天前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
大树889 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠9 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql