Nginx核心配置与实战排障:从基础到高可用

2026-06-23 15:26:57

# Nginx 核心配置与实战排障:从基础到高可用


Nginx 是后端开发绕不开的“看门人”。无论是部署Web应用、配置反向代理、处理跨域,还是应对大文件上传,你都需要和它打交道。但很多开发者的配置停留在“复制粘贴能用就行”的阶段,遇到问题就无从下手。


本文将基于实际工作场景,从**核心配置结构**、**反向代理与负载均衡**、**常见“深坑”排障**,到**性能调优与安全加固**,带你系统地掌握Nginx在生产环境中的最佳实践。


读完本文,你将能够:

- 看懂并编写结构清晰的Nginx配置文件

- 正确配置反向代理、负载均衡和动静分离

- 解决跨域、大文件上传超时等高频问题

- 为生产环境进行基本的性能优化和安全加固



 一、核心配置结构速览:先搭好骨架


Nginx的配置文件(通常是`nginx.conf`)结构清晰,遵循“分块”原则。我们先看骨架:


```nginx

# 全局块:影响整体运行的指令

user  nginx;

worker_processes  auto;  # 设为CPU核数最佳


# events块:影响网络连接

events {

    worker_connections  10240;  # 单个worker进程最大并发连接数

    use epoll;                 # Linux下使用高效的事件驱动模型

}


# http块:最核心的部分,包含所有Web配置

http {

    # 基础优化:文件类型、日志格式等

    include       /etc/nginx/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;       # 长连接超时时间


    # 上游服务器组(负载均衡)

    upstream backend_servers {

        server 192.168.1.10:8080 weight=3;  # 权重高,分配更多请求

        server 192.168.1.11:8080;

        server 192.168.1.12:8080 backup;    # 备份服务器

    }


    # server块:配置一个虚拟主机(网站)

    server {

        listen       80;

        server_name  www.example.com;


        # location块:匹配不同请求URI,进行精细化处理

        location / {

            root   /usr/share/nginx/html;

            index  index.html index.htm;

        }


        # 代理API请求到后端服务器

        location /api/ {

            proxy_pass http://backend_servers;

            proxy_set_header Host $host;

            proxy_set_header X-Real-IP $remote_addr;

        }

    }

}



二、反向代理与负载均衡:生产环境的核心

1. 标准反向代理配置(必需)

当你的应用跑在后端服务器(如Go、PHP-FPM)上时,Nginx作为代理,必须正确传递客户端真实信息:

nginx

location /api/ {
    proxy_pass http://backend_servers;  # 指向upstream组名或具体IP
    
    # 必备的header传递
    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;     # 传递协议(http/https)

    # 超时控制(关键!)
    proxy_connect_timeout 60s;      # 建立连接超时
    proxy_send_timeout 60s;         # 发送请求超时
    proxy_read_timeout 60s;         # 接收响应超时(大文件/慢接口需调大)}

2. 负载均衡策略

upstream 块中,你可以定义多种负载均衡策略:

策略参数说明
轮询默认按顺序轮流分配,适合无状态服务
权重weight=3给性能更好的机器分配更多请求
IP哈希ip_hash;同一客户端IP固定访问同一台后端,解决session共享问题
最少连接least_conn;转发给当前连接数最少的服务器

示例:利用IP哈希保持会话黏性

nginx

upstream backend_servers {
    ip_hash;  # 同一IP的请求总是发往同一台后端
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;}

3. 动静分离:提升性能

将静态资源(图片、CSS、JS)直接由Nginx处理,动态请求才转发给后端:

nginx

# 静态资源直接由Nginx提供location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
    root /var/www/static;          # 静态文件存放路径
    expires 30d;                   # 浏览器缓存30天
    add_header Cache-Control "public, immutable";
    access_log off;                # 不记录静态资源访问日志,减少I/O}# 动态请求走代理location / {
    proxy_pass http://backend_servers;
    # ... 其他proxy_set_header ...}

三、常见“深坑”与解决方案(重点)

1. 大文件上传报跨域错误(你的博客文章主题!)

问题描述:上传大文件(如>100MB)时,浏览器报跨域错误(CORS error),或直接返回413 Request Entity Too Large

真实原因:这不是真正的跨域问题,而是请求超时或请求体过大,导致Nginx提前中断连接,并返回错误响应。浏览器因未收到完整的CORS头信息,将其误报为跨域错误。

解决方案:四个配置联合解决:

nginx

http {
    # 1. 允许客户端请求体大小(默认1MB,必须调大)
    client_max_body_size 500M;   # 根据业务调整,如允许500MB文件上传

    server {
        location /upload/ {
            # 2. 代理超时时间大幅调高(秒)
            proxy_connect_timeout 600s;
            proxy_send_timeout 600s;
            proxy_read_timeout 600s;

            # 3. 代理缓冲区调大
            proxy_buffer_size 128k;
            proxy_buffers 4 256k;
            proxy_busy_buffers_size 256k;

            # 4. 关闭代理缓存(对大文件流式传输,避免磁盘I/O)
            proxy_buffering off;

            proxy_pass http://upload_backend;
            proxy_set_header Host $host;
            # ... 其他header
        }
    }}

关键点proxy_buffering off 尤其重要,它让Nginx以流式方式将数据转发给后端,而不是先将整个文件存到磁盘缓冲区,这能极大提升大文件上传性能并避免超时。

2. 跨域问题真正解法(CORS配置)

如果你的前端(如http://frontend.com)访问你的API(http://api.example.com),你需要在Nginx层面统一配置CORS头:

nginx

location /api/ {
    # ... 先配置好proxy_pass ...

    # 仅在需要处理预检请求(OPTIONS)时添加
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
    }

    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;}

3. 请求重定向次数过多(Loop)

现象:浏览器报 ERR_TOO_MANY_REDIRECTS

常见原因:Nginx配置了 proxy_pass 但后端应用又强制跳转到了 http 或另一个域名,形成了循环。

排查方法

  1. 检查 proxy_set_header Host $host; 是否正确传递了原始域名。

  2. 检查 proxy_set_header X-Forwarded-Proto $scheme;,确保后端能识别原始协议(尤其当Nginx处理了SSL时)。

  3. 在后端应用配置中,明确指定 trusted_proxies 或类似的设置。

四、SSL证书配置(HTTPS加密)

现在生产环境基本都是HTTPS,Let's Encrypt提供免费证书。

nginx

server {
    listen 443 ssl http2;  # 开启HTTP/2
    server_name www.example.com;

    # 证书路径
    ssl_certificate     /etc/nginx/ssl/www.example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/www.example.com.key;

    # 安全增强配置
    ssl_protocols TLSv1.2 TLSv1.3;               # 禁用过时的SSLv3/TLSv1.0
    ssl_ciphers HIGH:!aNULL:!MD5;                # 强加密套件
    ssl_prefer_server_ciphers on;

    # 启用HSTS(强制浏览器使用HTTPS,有效期6个月)
    add_header Strict-Transport-Security "max-age=15768000" always;

    location / {
        proxy_pass http://backend_servers;
        # ... 其他代理配置
    }}# HTTP 自动跳转 HTTPSserver {
    listen 80;
    server_name www.example.com;
    return 301 https://$server_name$request_uri;}

五、性能优化与安全加固

1. 性能调优关键参数

参数建议值说明
worker_processesauto等于CPU核数
worker_connections10240单个worker最大连接数,受系统ulimit -n限制
worker_rlimit_nofile65535设置worker进程最大打开文件数,需调整系统限制
keepalive_requests