Nginx 配置详解
📝 笔记摘要:Nginx 配置详解
nginx 干的事就两件:反向代理和负载均衡。下面按配置文件从外到内的顺序拆一遍。
1.配置文件的结构:

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

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 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 那四行一个都不能少。
