1
0
0

Nginx 配置详解

2026-10-18
2026-10-21

📝 笔记摘要:Nginx 配置详解

nginx 干的事就两件:反向代理和负载均衡。下面按配置文件从外到内的顺序拆一遍。

1.配置文件的结构:

nginx 配置文件结构图

  main —— 全局配置,指定进程信息
  events —— 配置工作模式以及连接数
  http —— http 块相关配置
   server —— 虚拟主机配置,可以多个
    location —— 路由规则,表达式
   upstream —— 集群,内网多服务器配置

2.逐行拆开看:

带注释的 nginx.conf

  worker_processes —— worker 子进程数量,官方建议最多 CPU 核数 × 2
  worker_connections —— 每个进程最大连接数,CentOS 7 默认打开文件数上限 65535
  include mime.types —— 引入能识别的文件类型表
  default_type —— mime.types 里没有的,按 application/octet-stream 输出,浏览器会当成下载
  sendfile on —— 零拷贝,文件传输不经过用户空间
  tcp_nopush —— 和 sendfile 配套,攒够一定大小再统一发,省 CPU
  keepalive_timeout 65 —— 长连接保持时间

提示:mime.types 决定 nginx 怎么解释文件类型。类型不认识就直接丢给浏览器下载,认识但浏览器不认识(比如某些 xml)就会以文本方式打开变乱码。

3.gzip:

gzip            on;
gzip_min_length 1k;
gzip_comp_level 5;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
gzip_disable "MSIE [1-6]\.";
gzip_vary      on;

  gzip_comp_level 是 1–9,越大压得越小也越吃 CPU,5 是个平衡点
  不建议压缩图片,jpg png 本身就是压缩格式,再压一遍纯浪费
  gzip_disable 是给 IE6 及以下用的,老浏览器不支持 gzip

4.反向代理:

  proxy_pass —— 转发到哪去,末尾斜杠决定 path 怎么拼
  proxy_set_header Host $host —— 把真实域名传下去,不写的话后端拿到的 host 是它自己
  proxy_set_header X-Real-IP $remote_addr —— 真实客户端 IP
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for —— 完整代理链,调试必加
  break —— 写在 location 里,命中之后不再往下匹配后面的 location

实际在用的一套:

server {
    listen       80;
    server_name  admin.example.com;

    location ^~ /ouser-web {
        proxy_pass http://127.0.0.1:8082/ouser-web;
        proxy_set_header   Host    $host;
        proxy_set_header   X-Real-IP   $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        break;
    }
    location ^~ / {
        proxy_pass http://10.0.0.163/;
        proxy_set_header   Host    $host;
        proxy_set_header   X-Real-IP   $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        break;
    }
}

提示:^~ 的意思是就算后面还有正则 location 也不去比了,直接用这条。/ouser-web 这种项目前缀必须用 ^~,否则会被下面的 / 抢走。

5.负载均衡:

upstream 负载均衡配置块

upstream webservers {
    server 192.168.169.130:8081;
    server 192.168.169.130:8082;
    server 192.168.169.130:8083;
}

  upstream 必须写在 http 块里,写进 server 里 -t 直接报错
  默认轮询(round robin),加 weight= 配权重
  加 ip_hash 按客户端 IP 固定后端,做会话保持时用
  后端要健康检查,得单独装 ngx_http_upstream_hc_module

6.location 的匹配顺序:

  = 精确匹配,优先级最高
  ^~ 匹配后不再走正则
  ~ 正则,区分大小写
  ~* 正则,不区分大小写
  / 默认前缀匹配

注意:普通前缀匹配是最长匹配,不是「先定义先匹配」。谁长谁赢。

7.跨域:

server {
    listen       8080;
    server_name  localhost;
    location  / {
        add_header Access-Control-Allow-Origin 'http://localhost:4443' always;
        add_header Access-Control-Allow-Headers '*';
        add_header Access-Control-Allow-Methods '*';
        add_header Access-Control-Allow-Credentials 'true';
        if ($request_method = 'OPTIONS') {
            return 204;
        }
        proxy_pass  http://localhost:9081;
    }
}

提示:那个 if 是关键。浏览器发 OPTIONS 预检请求,不拦掉的话后端收到的是 405,always 也不能少,不然错误响应上这几个头就没了。

注意:Access-Control-Allow-Origin 写 * 和 Allow-Credentials true 不能同时用,浏览器直接拒。

8.防盗链:

location ~*\.(png|jpg|gif) {
    valid_referers example.com;
    if ($invalid_referer) {
        return 403;
    }
    root /usr/local/nginx/html;
}

提示:valid_referers 里最好写全协议和端口。同域不同端口也会被拦掉,排查「图片本地能看线上不显示」时先查这里。

9.switch hosts 做本地联调:

配完 nginx 还要把域名指到本机,才能在浏览器里按域名访问 staging 环境:

127.0.0.1   admin.example.com

提示:改完 hosts 浏览器还是走老 IP,是 DNS 缓存或者中间代理的问题,清一下缓存再试。

10.出问题先对号入座:

  502 —— 后端挂了或端口不通。先 curl 127.0.0.1:端口 看服务本身活着没
  504 —— 后端响应超时,调 proxy_read_timeout
  403 —— 目录或文件权限问题,或者 basic 认证没过
  404 —— root 路径写错,或者请求路径没匹配上任何 location
  加了 break 就 404 —— break 之后的 location 不再匹配,该走的路径没人接
  改了配置没反应 —— 忘了 reload,或者 include 路径写错导致那个文件根本没被读到
  reload 没报错但行为没变 —— 先 nginx -t,多半是有语法错误被跳过了

💡 补充几个原文没写的:

proxy_pass 末尾的斜杠很关键。 location /a 配 proxy_pass http://x/ 会把 /a 剥掉,不加斜杠就会把 /a 拼到后端路径前面。

后端拿到的 IP 不对,八成是忘了 proxy_set_header X-Forwarded-For,默认情况下后端只能看到 nginx 这一跳。

proxy_read_timeout 默认 60 秒,跑长任务的后端要调大,不然周期性 504。

大文件下载可以加 proxy_buffering off,省一层中转内存。

出处:跨域、防盗链这两节的思路参考了 CSDN 上 CrazyQiQi 和 Tiksty 的文章,遵循 CC BY-SA 4.0。

🔥 一句话总结:项目前缀用 ^~ 卡死,proxy_pass 末尾的斜杠决定路径怎么拼,proxy_set_header 那四行一个都不能少。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!