Ceiling

Nginx 配置详解

Nginx 是生产环境最常用的反向代理和静态资源服务器之一,它的功能几乎都由配置文件驱动。理解了配置文件的层级结构和指令继承规则,就掌握了 Nginx 的大部分用法。本文从配置文件结构讲起,逐步展开 server、location、反向代理、HTTPS 等核心配置,最后整理常用的实战配置片段。

一、配置文件位置与整体结构

Nginx 的主配置文件通常是 /etc/nginx/nginx.conf,站点配置习惯放在 /etc/nginx/conf.d/ 目录下(以 .conf 结尾的文件会被自动加载)。修改配置后务必先校验语法:

# 检查配置文件语法
nginx -t

# 校验通过后平滑重载,不中断服务
nginx -s reload

配置文件由若干「块」嵌套组成,层级关系如下:

graph TD A[main 全局块] --> B[events 块] A --> C[http 块] C --> D[server 块] D --> E[location 块] C --> F[upstream 块]

各块的分工:

作用范围主要内容
main全局进程数、运行用户、日志路径等
events全局连接处理模型、单进程连接数上限
http所有站点MIME 类型、gzip、超时、日志格式等
server单个虚拟主机端口、域名、站点根目录
location单个路径URL 匹配规则、代理转发、静态资源处理
upstreamhttp 内后端服务器集群,用于负载均衡

指令遵循就近继承原则:子块没写某项配置时,自动继承父块的值;子块写了则以子块为准。

二、main 全局块

# 运行 Nginx worker 进程的系统用户
user nginx;

# worker 进程数,通常设为 CPU 核心数或 auto
worker_processes auto;

# 错误日志路径及级别:debug > info > notice > warn > error
error_log /var/log/nginx/error.log warn;

pid /run/nginx.pid;

# 每个 worker 可打开的最大文件描述符数
worker_rlimit_nofile 65535;
worker_processes auto 让 Nginx 自动按 CPU 核心数创建进程,绝大多数场景直接用即可。

三、events 块

events 块决定 Nginx 如何处理客户端连接:

events {
    # 每个 worker 的最大并发连接数(含代理连接)
    worker_connections 10240;

    # Linux 下使用 epoll 事件模型,高性能必配
    use epoll;

    # 允许 worker 一次性接受所有新连接
    multi_accept on;
}

单机最大并发数 = worker_processes × worker_connections,按实际并发压力调整。

四、http 块

http 块管理所有站点的公共配置,常见项:

http {
    # 引入 MIME 类型映射,保证 css/js/图片等返回正确的 Content-Type
    include mime.types;
    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;

    # 长连接保持时间
    keepalive_timeout 65;

    # 开启 gzip 压缩,减小文本类响应体积
    gzip on;
    gzip_min_length 1k;
    gzip_types text/plain text/css application/json application/javascript application/xml;

    # 加载 conf.d 下的所有站点配置
    include /etc/nginx/conf.d/*.conf;
}

五、server 块:虚拟主机

每个 server 块代表一个虚拟主机,同一台机器可以靠端口或域名区分任意多个站点:

server {
    # 监听 80 端口
    listen 80;

    # 匹配的域名,多个用空格分隔;_ 表示兜底站点
    server_name www.ceiling.cloud ceiling.cloud;

    # 站点根目录
    root /var/www/site;

    # 默认首页
    index index.html index.htm;

    # 静态资源直接返回,找不到时回落到首页(适合单页应用)
    location / {
        try_files $uri $uri/ /index.html;
    }

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

六、location 匹配规则

location 是配置里最容易出错的部分,核心在于匹配优先级。规则从高到低:

优先级写法含义
1location = /uri精确匹配,命中即停止搜索
2location ^~ /uri前缀匹配,命中后不再检查正则
3location ~ 正则区分大小写的正则匹配
4location ~* 正则不区分大小写的正则匹配
5location /uri普通前缀匹配,选最长前缀
6location /兜底匹配

匹配流程:先找所有前缀匹配,记下最长的那个;再按顺序检查正则,正则命中就用正则;正则都不命中才回退到最长前缀(除非它是 ^~)。

# 精确匹配首页
location = / {
    return 301 /home;
}

# 静态资源单独处理,设置缓存
location ^~ /static/ {
    expires 30d;
}

# 正则匹配图片类文件
location ~* \.(jpg|png|gif|webp)$ {
    expires 7d;
}

# API 前缀转发到后端
location /api/ {
    proxy_pass http://127.0.0.1:3000/;
}

注意 proxy_pass 末尾的 /:带 / 时会把匹配到的前缀剥掉(/api/user/user),不带则原样转发(/api/user/api/user)。

七、反向代理与负载均衡

1. 基本反向代理

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

    # 透传客户端真实信息,后端才能拿到真实 IP 和域名
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # 代理超时设置
    proxy_connect_timeout 10s;
    proxy_read_timeout 60s;
}

2. WebSocket 支持

长连接(如 WebSocket)需要额外加上协议升级的头:

location /ws/ {
    proxy_pass http://127.0.0.1:8081;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 3600s;
}

3. upstream 负载均衡

upstream backend {
    # 负载均衡策略:默认轮询,还可选 least_conn、ip_hash、weight
    server 192.168.1.10:8081 weight=3;
    server 192.168.1.11:8081;
    server 192.168.1.12:8081 backup;   # 备份节点,其他节点全挂时才启用

    keepalive 32;   # 与后端保持的空闲长连接数
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
    }
}

常用策略:ip_hash 按客户端 IP 固定分配(解决 session 粘滞);least_conn 优先分配给连接数最少的节点。

八、HTTPS 配置

HTTPS 站点需要证书文件(_bundle.crt 为证书链、.key 为私钥),并建议把 HTTP 统一跳转到 HTTPS:

# HTTP 自动跳转 HTTPS
server {
    listen 80;
    server_name www.ceiling.cloud;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name www.ceiling.cloud;

    ssl_certificate     /etc/nginx/certs/ceiling.cloud_bundle.crt;
    ssl_certificate_key /etc/nginx/certs/ceiling.cloud.key;

    # 只启用安全的协议版本与加密套件
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # 会话复用,减少握手开销
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    location / {
        root /var/www/site;
        index index.html;
    }
}

证书续期或更换后,执行 nginx -t && nginx -s reload 即可生效。

九、常用实战配置片段

1. 跨域(CORS)

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 "Content-Type, Authorization" always;
    add_header Access-Control-Allow-Credentials "true" always;

    # 预检请求直接返回 204
    if ($request_method = OPTIONS) {
        return 204;
    }
    proxy_pass http://127.0.0.1:3000/;
}

2. 限流防爆刷

http {
    # 按客户端 IP 限流,每秒 10 个请求,突发最多排队 20 个
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

    server {
        location /api/ {
            limit_req zone=api_limit burst=20 nodelay;
            proxy_pass http://backend;
        }
    }
}

3. 静态资源缓存

location ~* \.(js|css|png|jpg|woff2)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}

4. 禁止访问隐藏文件

location ~ /\. {
    deny all;
}

5. 域名与路径重写

# 旧路径永久重定向到新路径
rewrite ^/old-blog/(.*)$ /blog/$1 permanent;

十、常用运维命令

nginx -t                # 校验配置语法
nginx -s reload         # 平滑重载配置
nginx -s stop           # 立即停止
nginx -s quit           # 处理完当前请求后退出
nginx -V                # 查看版本及编译参数

systemctl status nginx  # 查看服务状态
systemctl restart nginx # 重启服务

# 查看指定配置生效情况(需要 1.19.6+)
nginx -T | grep server_name

排查问题时先看 /var/log/nginx/error.log,再结合 nginx -t 定位是哪一行的语法或继承出了问题。

十一、小结

  • 配置文件按 main → events → http → server → location 层层嵌套,指令就近继承;
  • server 定义虚拟主机,location 决定每个路径怎么处理,匹配优先级是 = > ^~ > 正则 > 前缀;
  • proxy_pass 末尾有无 / 会改变转发路径,是新手最常踩的坑;
  • HTTPS 站点记得配置 HTTP 到 HTTPS 的 301 跳转;
  • 改完配置永远先 nginx -t 校验,再 nginx -s reload 生效。

日常部署中,「静态资源用 root、动态请求用 proxy_pass、HTTPS 用 443 + 证书」这套组合就能覆盖绝大多数场景。