Nginx反向代理后端健康检查故障转移配置 Nginx
前言
多台后端服务做负载均衡时,某台宕机不能继续把请求发过去。Nginx upstream 可以配置备用服务器和失败计数,自动剔除故障节点、恢复后再纳入。注意 Nginx 原生被动健康检查的局限,本文讲解 upstream 负载、max_fails/fail_timeout、backup 备用节点、与主动检查方案区别。
操作步骤
1. 定义 upstream 多节点
upstream backend {
server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8083 backup;
}
2. 反向代理引用
server {
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
3. 参数说明
- max_fails:连续失败次数阈值;fail_timeout:判定故障的时间窗。
- backup:备用节点,主节点全挂才启用。
4. 配置健康检查响应超时
proxy_connect_timeout 5s;
proxy_read_timeout 15s;
5. 校验并重载
nginx -t
nginx -s reload
6. 验证故障转移
停掉一台后端,观察请求是否落到其余节点。
常见坑
- 原生 upstream 是被动检查,只在请求失败时计数,不会主动探活。
- fail_timeout 过后不会自动探测恢复,要等新请求触发。
- backup 节点平时不接收流量,只在主节点全挂时顶上。
- 健康检查需要主动探测时要用商业版或第三方模块。
- 后端返回 5xx 才计失败,正常响应不计。
- 多 worker 计数各自独立,故障判定可能不一致。
- 会话粘滞需求需额外配置 ip_hash,别和故障转移混淆。
总结
Nginx 被动故障转移靠 max_fails/fail_timeout 计数失败,backup 兜底。它简单够用但不主动探活,强需求用主动健康检查模块或负载均衡器。配置后停节点实测故障转移,确认请求落到健康后端。
遇到问题加QQ23979811 协助处理
Nginx访问控制IP白名单配置限制来源 Nginx
前言
后台、管理接口、测试环境只允许固定 IP 访问,其他来源一律拒绝。Nginx 的 allow/deny 指令可以按 IP 段做白名单,配合 403 返回。本文讲解 location 级白名单、整站白名单、拒绝其余所有 IP、多 IP 与网段写法,以及反代时取真实 IP 的注意事项。
操作步骤
1. 只允许指定 IP 访问后台
location /admin/ {
allow 1.2.3.4;
allow 10.0.0.0/8;
deny all;
proxy_pass http://backend;
}
allow 写可信来源,deny all 拒绝其余全部。
2. 整站白名单(内网开放)
server {
listen 80;
allow 192.168.1.0/24;
allow 1.2.3.4;
deny all;
}
3. 放行多个 IP 和网段
allow 1.1.1.1;
allow 2.2.2.0/24;
allow 3.3.3.3;
deny all;
4. 校验并重载
nginx -t
nginx -s reload
5. 测试访问控制
curl -I https://域名/admin/
不在白名单的 IP 返回 403,白名单 IP 正常进入。
6. 反代场景取真实 IP
经过 CDN 或反代时,$remote_addr 是代理 IP,需先配 real_ip 模块还原访客 IP,否则白名单全部失效。
常见坑
- 顺序错误:deny all 写在 allow 前面,所有 IP 都被拒。
- 经过 CDN 直接 deny all,真实访客全被挡。
- 只对 location 配白名单,其他路径仍可访问。
- 办公 IP 是动态的,白名单要定期更新。
- 网段写法错误,/24 写成 255.255.255 无效。
- 同时用了云安全组,两层规则要保持一致。
- 白名单不能替代登录鉴权,它只是网络层限制。
总结
IP 白名单用 allow 列可信来源、deny all 兜底,可放 server 整站或 location 单路径。反代必须先还原真实 IP。白名单适合后台、测试、内网接口,仍要配合账号登录,不能把它当成唯一防线。
遇到问题加QQ23979811 协助处理
Nginx按User-Agent拦截恶意爬虫配置 Nginx
前言
很多恶意爬虫、扫描器会带着固定或伪造的 User-Agent 疯狂抓取接口、图片,消耗带宽和服务器资源。在 Nginx 层按 User-Agent 直接返回 403,比应用层判断更省资源,也不影响正常浏览器。本文讲解 map 定义黑名单、location 拦截、放行正常 UA、常用恶意 UA 写法,以及误伤规避。
操作步骤
1. 在 http 块用 map 标记恶意 UA
map $http_user_agent $bad_bot {
default 0;
~*curl 1;
~*scrapy 1;
~*python-requests 1;
~*httpclient 1;
~*semrushbot 1;
~*ahrefsbot 1;
~*masscan 1;
}
2. 在 server 或 location 拦截
if ($bad_bot = 1) {
return 403;
}
3. 只拦截接口或整站
整站拦截放在 server 块;只保护接口放 location:
location /api/ {
if ($bad_bot = 1) { return 403; }
proxy_pass http://backend;
}
4. 放行搜索爬虫(可选)
百度、谷歌 UA 正常收录,不要误封:
map $http_user_agent $bad_bot {
default 0;
~*googlebot 0;
~*baiduspider 0;
~*curl 1;
}
5. 校验并重载
nginx -t
nginx -s reload
6. 用 curl 测试是否被拦
curl -A "curl/7.0" https://域名/ -I
返回 403 即生效,正常浏览器 UA 访问不受影响。
常见坑
- 正则太宽泛,把正常 App 的 UA 也匹配进去,误伤用户。
- 只在 location 写 if,其他 location 没覆盖,爬虫换路径绕过。
- 恶意 UA 可伪造,UA 拦截只能挡低阶爬虫,不能替代频控。
- 大小写匹配用 ~* 忽略大小写,避免漏封。
- 搜索引擎爬虫被封导致收录下降,务必放行官方 UA。
- map 写在 server 内无效,必须放在 http 层。
- 大量拦截规则影响匹配性能,控制规则数量。
总结
UA 拦截靠 map 给恶意 UA 打标记,再用 if 返回 403,放 server 或对应 location。规则要精准、放行正规搜索爬虫,并用 curl 换 UA 测试。它是辅助手段,真正的高频恶意访问还要配合 limit_req 限流和 IP 封禁。
遇到问题加QQ23979811 协助处理
Nginx日志按天切割logrotate轮转配置教程 Nginx
前言
Nginx 访问日志默认持续写入一个文件,时间一长体积巨大,查看和分析都困难,甚至占满磁盘。logrotate 是系统自带的日志轮转工具,按天切割、压缩旧日志、保留指定天数。本文讲解为 Nginx 配置按天切割、重载信号、验证轮转的完整配置。
操作步骤
1. 新建 Nginx 切割配置
vi /etc/logrotate.d/nginx
写入:
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0640 nginx adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
2. 参数说明
- daily:按天切割;rotate 30:保留 30 份;compress:压缩旧日志。
- postrotate:切割后发 USR1 信号让 Nginx 重新打开日志文件。
3. 手动测试一次轮转
logrotate -f /etc/logrotate.d/nginx
4. 查看切割结果
ls -lh /var/log/nginx/
5. 确认 logrotate 定时任务存在
cat /etc/cron.daily/logrotate
常见坑
- 切割后不发 USR1 信号,Nginx 仍写旧句柄,新日志进不了新文件。
- nginx.pid 路径与实际不一致,postrotate 命令失效。
- create 的属主属组写错,新日志无写入权限。
- rotate 天数设太短,历史日志查不到;太长又占磁盘。
- 只切割 access.log 漏了 error.log,通配 *.log 更稳妥。
- 自定义日志路径不在 /var/log/nginx,配置路径要改。
- 手动 -f 测试会立即切割,正式环境注意时机。
总结
Nginx 日志切割靠 logrotate:daily 按天、rotate 控制保留数、postrotate 发 USR1 让 Nginx 重开日志。配置后用 logrotate -f 测试,再看目录确认生成新文件。日志保留天数按合规和磁盘容量平衡,压缩旧日志节省空间。
遇到问题加QQ23979811 协助处理
Nginx开启HTTP2提升并发访问速度配置 Nginx
前言
HTTP/1.1 一个连接上多个请求需要排队,HTTP/2 多路复用让一个连接并行传输多个资源,网页静态文件多时提速明显。HTTP/2 必须基于 HTTPS,纯 HTTP 无法启用。本文讲解确认 Nginx 是否带 http_v2 模块、监听配置、兼容降级、验证协议的完整步骤。
操作步骤
1. 检查是否支持 HTTP2
nginx -V 2>&1 | grep http_v2_module
有输出说明已编译支持;没有则需重新编译或用宝塔勾选模块。
2. 修改 443 监听行
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /www/ssl/example.crt;
ssl_certificate_key /www/ssl/example.key;
location / {
root /www/example;
index index.html;
}
}
3. 80 端口保持普通 HTTP 并跳转
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
4. 校验并重载
nginx -t
nginx -s reload
5. 验证是否为 h2
curl -I --http2 https://example.com
浏览器开发者工具网络面板协议列显示 h2 即成功。
常见坑
- listen 只写 http2 不写 ssl,报错启动失败,http2 必须配 SSL。
- Nginx 版本太老不带模块,需重新编译。
- CDN 接入后源站 http2 不一定对外生效,取决于 CDN。
- 老客户端自动降级 HTTP/1.1,无需额外处理。
- 开 http2 同时开启压缩会增加 CPU,低配机器留意负载。
- 多个证书站点共用 server,配置写法不变。
- HTTP/2 提升主要在资源多的页面,纯接口站点收益有限。
总结
开启 HTTP2 三要素:Nginx 带 http_v2 模块、listen 443 ssl http2、站点启用 HTTPS。开启后用 curl --http2 或浏览器面板验证 h2。它对图片、JS、CSS 多的页面提升明显,结合 gzip/brotli 压缩和静态缓存效果更好。
遇到问题加QQ23979811 协助处理
Nginx配置静态资源expires缓存规则提速 Nginx
前言
图片、CSS、JS、字体等静态资源每次都向服务器重新请求,浪费带宽也拖慢页面。Nginx 的 expires 指令通过设置 Cache-Control 过期时间,让浏览器本地缓存静态资源,重复访问不再回源,配合版本号可解决更新不刷新问题。本文给出按类型设置缓存、html 不缓存、版本号破缓存、重载验证的完整配置。
操作步骤
1. 在 server 或 http 块添加缓存规则
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff2?|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
2. HTML 不缓存,保证及时更新
location ~* \.html$ {
expires -1;
add_header Cache-Control "no-cache";
}
3. 图片单独设更长缓存
location ~* \.(png|jpg|jpeg|gif|webp|svg)$ {
expires 90d;
add_header Cache-Control "public";
}
4. 带版本号的资源长期缓存
location ~* \.(css|js)\?v=[0-9.]+$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
5. 校验并重载
nginx -t
nginx -s reload
6. 浏览器验证响应头
curl -I https://域名/style.css
响应头出现 Cache-Control 和 Expires 即生效。
常见坑
- 把 HTML 也长期缓存,内容更新后访客看到旧页面。
- 缓存时间过长,静态文件更新后浏览器仍用旧版,需加版本号 hash。
- 正则写错导致动态接口被当成静态缓存。
- CDN 已缓存源站,Nginx expires 只影响浏览器,源站更新需刷新 CDN。
- immutable 只对带版本号资源使用,避免误伤。
- add_header 在 location 内会覆盖上层的其他 add_header,注意合并。
- 移动端强缓存配合 Service Worker 时要统一策略。
总结
expires 按资源类型分层缓存:图片字体长缓存、CSS/JS 中长缓存、HTML 不缓存。更新靠文件名版本号或 hash 破缓存,而不是缩短缓存时间。配置后用 curl 看响应头确认,再结合 CDN 刷新策略形成完整缓存链。
遇到问题加QQ23979811 协助处理
Nginx上传文件413 Request Entity Too Large解决 Nginx
前言
后台上传图片、附件或视频时,Nginx 返回 413 Request Entity Too Large,文件传不上去。这是 Nginx 的客户端请求体大小限制在拦截,默认通常只有 1MB,而 PHP 也有自己的上传限制,两层都要放开。本文讲解 Nginx 的 client_max_body_size 配置位置、与 PHP upload_max_filesize/post_max_size 的配合,以及验证方法。
操作步骤
1. 在 http 或 server/location 块设置上传大小
http {
client_max_body_size 50m;
}
也可只在某个站点:
server {
client_max_body_size 50m;
}
2. 修改 PHP 上传限制(php.ini)
php --ini
找到 php.ini,修改:
upload_max_filesize = 50M
post_max_size = 55M
post_max_size 要略大于 upload_max_filesize。
3. 重启 PHP-FPM 并重载 Nginx
systemctl restart php-fpm
nginx -t
nginx -s reload
4. 验证 Nginx 限制
curl -X POST -H "Content-Length: 60000000" http://域名/ -o /dev/null -w "%{http_code}\n"
超过限制仍返回 413,未超过则不报错。
5. 宝塔面板用户
站点设置 → 配置文件里直接加 client_max_body_size,或在上传限制选项里调整,同时改 PHP 上传大小。
常见坑
- 只改了 Nginx,PHP 的 upload_max_filesize 仍为 2M,文件传到一半被 PHP 拒绝。
- post_max_size 小于 upload_max_filesize,上传永远超限。
- client_max_body_size 写在错误层级,被上层默认值覆盖。
- 改完 php.ini 没重启 php-fpm,参数不生效。
- 云服务器或 CDN 还有上传大小限制,Nginx 放开了但中间层拦截。
- 大文件上传还需要调整超时时间,避免传输过程中断。
- 单位大小写注意,m 和 M 均可,不要写成 mb。
总结
413 的解决是两层联动:Nginx 的 client_max_body_size 放开上限,PHP 的 upload_max_filesize 和 post_max_size 同步放大,再重启 php-fpm、重载 Nginx。CDN 和云网关的限制要单独确认。上传功能上线前用超限文件实测,确认两层都不拦截。
遇到问题加QQ23979811 协助处理
Nginx反向代理WebSocket长连接超时配置 Nginx
前言
用 Nginx 反向代理 WebSocket 服务时,经常出现连接建立几十秒后自动断开、前端报 1006、长连接被中断的问题。原因是 Nginx 默认把 HTTP 连接当成短连接,缺少 WebSocket 升级头和长连接超时参数。本文给出完整的 WebSocket 反代配置,包含 Upgrade 头、Connection 映射、读写超时,并说明轮询与 wss(加密)场景。
操作步骤
1. 后端 WebSocket 服务示例(端口 8080)
先确认后端 ws 服务正常监听。
2. 在 http 块定义长连接映射(可选推荐)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
3. WebSocket 反代 server 块
server {
listen 80;
server_name ws.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
4. wss(HTTPS)WebSocket
server {
listen 443 ssl;
server_name ws.example.com;
ssl_certificate /www/ssl/ws.crt;
ssl_certificate_key /www/ssl/ws.key;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
5. 校验并重载
nginx -t
nginx -s reload
6. 验证长连接
用 wscat 或前端页面连接,保持空闲超过默认 60 秒不断开即成功。
常见坑
- 漏写 Upgrade 和 Connection 头,握手失败,连接无法升级为 WebSocket。
- 没有 map,Connection 写死 upgrade,普通 HTTP 请求也被强制升级。
- proxy_read_timeout 默认 60 秒,空闲连接被 Nginx 主动断开,要调大。
- 后端服务本身有心跳超时,两端超时不一致仍会断。
- 经过多层代理(CDN、网关),中间层也需要支持长连接和 WebSocket。
- HTTPS 下前端必须用 wss,混用 ws 会被浏览器拦截。
- 多 location 复用代理配置时,超时参数要在需要的块里单独设置。
总结
WebSocket 反代三要素:proxy_http_version 1.1、Upgrade/Connection 升级头、调大 proxy_read_timeout。用 map 区分升级与关闭,避免误伤普通请求。配置后用长连接压测观察是否在空闲后断开,同时检查后端心跳与中间代理链路。
遇到问题加QQ23979811 协助处理
Nginx禁止直接用IP访问网站返回444配置 Nginx
前言
很多服务器直接用 IP 地址就能打开网站,搜索引擎可能收录 IP 页面,恶意扫描也会直接访问 IP。规范做法是:只允许绑定域名访问,直接用 IP 访问时让 Nginx 返回 444(Nginx 专有状态码,表示直接断开连接,不返回任何内容)。本文给出 server 块配置、默认服务阻断、重载验证的完整写法,适配单站点和多站点。
操作步骤
1. 在站点配置前增加一个默认 server
在 nginx.conf 或站点配置文件最前面加:
server {
listen 80 default_server;
server_name _;
return 444;
}
default_server 表示所有未匹配域名的请求都落到这个块。
2. HTTPS 同理阻断 IP 访问
server {
listen 443 ssl default_server;
server_name _;
ssl_certificate /www/ssl/default.crt;
ssl_certificate_key /www/ssl/default.key;
return 444;
}
没有默认证书时,HTTPS 的 IP 访问会先报证书错误,可只阻断 80。
3. 正式站点 server 块只写域名
server {
listen 80;
server_name www.example.com example.com;
root /www/example;
index index.html;
}
4. 校验并重载 Nginx
nginx -t
nginx -s reload
5. 验证 IP 访问被拒绝
curl -I http://服务器IP
返回空响应、连接被断开,HTTP 状态为 444 即成功;域名访问保持正常。
常见坑
- 只写 servername 没加 default_server,IP 请求仍落到第一个 server 块。
- 多站点配置里有多个 listen 80,default_server 必须唯一,否则冲突报错。
- 用 return 403 会返回状态码和页面,444 才是直接断开,按需选择。
- HTTPS 阻断缺少默认证书,浏览器先报证书警告,达不到静默断开。
- 改完没 nginx -t 校验,语法错误导致 reload 失败、全站中断。
- 反代到后端时,IP 访问可能被上游服务响应,务必在 Nginx 层先拦截。
总结
禁止 IP 访问的核心是配置一个 default_server 块,server_name 用下划线占位并 return 444,让所有未绑定域名的请求直接断开。正式站点只保留域名 server 块。配置后用 curl 测 IP、用域名分别验证,确保只拦 IP 不误伤正常访问。
遇到问题加QQ23979811 协助处理
Nginx绑定域名配置 Nginx
Nginx绑定域名配置
引言
一台服务器跑多个站点,靠server_name区分访问哪个域名,配合DNS解析和站点根目录,Nginx按Host头把请求路由到对应虚拟主机。配置顺序写错或server_name不匹配,会落到默认站点。
基础域名站点
server {
listen 80;
server_name www.example.com example.com;
root /var/www/example;
index index.html index.php;
}
server_name可并列写主域名和裸域名,root指向站点目录。
裸域名跳转到www
server {
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
避免两个域名都解析内容造成重复收录,统一到一个规范域名。
多个域名并列
server_name api.example.com admin.example.com;
同一套站点对应多个子域名时直接空格分隔。
反向代理绑定域名
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
}
域名指向后端服务,记得把Host头透传给上游。
配置后检查重载
nginx -t
nginx -s reload
先测语法再平滑重载,reload不断连接。
匹配规则
- 精确域名优先,然后通配符,最后默认站点;
- 没匹配上server_name的请求落到default_server;
- 通配符*.example.com不能匹配example.com裸域;
- 多站点注意别让无关域名被默认站点接住。
注意事项
- DNS要先把A记录解析到服务器IP,否则域名打不开;
- server_name区分大小写但通常小写;
- 80改443需另配SSL证书块;
- return 301统一域名利于SEO避免重复;
- 防火墙和安全组放行80、443;
- 多个server块listen 80,靠server_name分流。
总结
server_name在server块绑定域名,可并列多个,裸域301跳www统一规范,反代时透传Host,改完nginx -t检查再reload。匹配精确优先于通配符,未命中走默认站点,前提是DNS解析到位、端口放行,统一域名有助于SEO避免重复收录。
Nginx监听端口配置 Nginx
Nginx监听端口配置
引言
listen是server块的第一行指令,决定Nginx在哪个端口接收请求。一个server监听一个端口加域名组合,多站点靠server_name区分,多端口靠listen叠加。配错端口是最常见的502和无法访问根源。
基础HTTP监听
server {
listen 80;
server_name example.com;
root /var/www/site;
index index.html;
}
监听80端口,匹配example.com域名的请求进这个站点。
HTTPS监听
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
}
443必须加ssl关键字,同时配证书和私钥路径。
监听多个端口
server {
listen 80;
listen 8080;
server_name example.com;
}
一个server块写多行listen,80和8080都走同一套配置。
只监听指定IP
listen 127.0.0.1:8080;
只绑回环地址,外部访问不到,适合内部管理接口。
80跳转到443
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
单独一个80 server做永久跳转,把HTTP请求引导到HTTPS。
默认服务器
server {
listen 80 default_server;
}
default_server指定未匹配域名时的兜底站点,防直接用IP访问暴露默认页。
注意事项
- 端口冲突先ss -tlnp查占用,别盲目改;
- 443漏写ssl会导致证书不生效;
- 云服务器还要在安全组放行对应端口;
- listen不带IP默认绑0.0.0.0全部网卡;
- 改端口后先nginx -t再reload;
- 301跳转的旧URL参数用$request_uri保留。
总结
listen 80配HTTP,listen 443 ssl配HTTPS并带证书,多行listen监听多端口,IP:端口限定绑定网卡,80 server用return 301跳HTTPS,default_server做域名兜底。改前ss查占用、nginx -t校验、安全组放行,绑定IP时注意内外网可达性,跳转用$host和$request_uri保住完整地址。
Nginx配置检查测试 Nginx
Nginx配置检查测试
引言
改完Nginx配置直接reload最容易踩坑:语法错、证书路径错、端口被占会导致Nginx起不来甚至站点全挂。规范流程是先检查语法,通过后再平滑重载,出问题能快速回退。
语法检查
nginx -t
检查默认配置文件语法,输出syntax ok和test is successful才说明配置无误。
指定配置文件检查
nginx -t -c /etc/nginx/nginx.conf
自定义路径时用-c指定,避免检查错文件。
平滑重载
nginx -s reload
不中断现有连接重新加载配置,改动生效不宕机。
查看编译参数和版本
nginx -V
大写V看版本和编译模块,确认是否包含ssl、gzip、stream等模块。
打印生效配置
nginx -T
大写T会把所有include进来的配置打印出来,排查重复server或覆盖时用。
出错常见原因
- 括号不配对、分号漏写;
- 证书key路径不存在或权限600不对;
- listen端口已被其他进程占用;
- upstream后端地址写错;
- include路径下的文件本身语法错。
注意事项
- 永远先-t再reload,禁止跳过检查;
- 改配置前备份原文件,出错可立刻回退;
- -T输出很长,重定向到文件再查;
- reload失败先看error.log定位行号;
- 生产环境改完curl本机验证再放行;
- 多台机器逐台灰度,不要一次全改。
总结
nginx -t检查语法,-c指定文件,-s reload平滑生效,-V看编译模块,-T打印完整配置。铁律是先检查通过再重载,改前备份、出错看error.log、本机curl验证后再上线,生产逐台灰度,避免一次改全量导致整站不可用。
Nginx默认站点配置 Nginx
Nginx默认站点配置
引言
直接用IP或未匹配到server_name的域名访问时,Nginx会落到默认站点。装好Nginx自带的欢迎页就是默认server,安全上建议改掉,避免暴露版本或被扫描利用。
默认站点如何确定
同一端口下,第一个server块、或带default_server标记的就是默认站点:
server {
listen 80 default_server;
server_name _;
root /usr/share/nginx/html;
index index.html;
}
server_name用_占位,表示匹配任意未命中的主机名。
配置占位拒绝页
对外只暴露正式站点时,默认站点直接返回444或简单403:
server {
listen 80 default_server;
server_name _;
return 444;
}
444是Nginx特有,直接断开连接,不返回内容。
隐藏版本号
http {
server_tokens off;
}
避免错误页暴露Nginx版本,减少针对性漏洞扫描。
自定义默认首页
server {
listen 80 default_server;
server_name _;
root /var/www/default;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
多端口默认
HTTPS同理,443也要配default_server:
server {
listen 443 ssl default_server;
server_name _;
# 自签或占位证书,否则握手失败
return 444;
}
注意事项
- 一台机器同端口只能有一个default_server;
- 不配默认站,未匹配域名会落到第一个server,可能串站点;
- 改完nginx -t校验再reload;
- 云主机IP直扫建议默认站返回444,不暴露首页;
- 区分default_server和servername ,前者是优先级标记;
- SSL默认站必须有证书,否则浏览器握手报错。
总结
默认站点由default_server或同端口首个server决定,用server_name _占位。安全做法是把默认站返回444拒绝、server_tokens off隐藏版本,443也要配默认拒绝站,避免IP直扫串到正式站点。改完务必-t校验再reload。
Nginx代理缓存配置 Nginx
Nginx代理缓存配置
引言
反向代理每次都回源取页面,后端压力大、首屏慢。Nginx自带proxy_cache,把后端响应存到本地磁盘,命中时直接返回,既减轻源站又加快响应,适合静态资源和不常变的页面。
定义缓存区
http块里先声明缓存目录和大小:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=mycache:10m max_size=1g inactive=7d;
- keys_zone=mycache:10m 是缓存名和索引内存;
- max_size=1g 磁盘上限;
- inactive=7d 7天没访问自动清理。
代理站点启用缓存
server或location块:
location / {
proxy_cache mycache;
proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 304 1h;
proxy_cache_valid 404 1m;
proxy_cache_methods GET HEAD;
proxy_pass http://backend;
}
200/304缓存1小时,404只存1分钟。
命中状态标识
加响应头方便排查:
add_header X-Cache-Status $upstream_cache_status;
HIT命中、MISS未命中、EXPIRED过期、BYPASS绕过。
绕过缓存的场景
登录后动态内容不缓存:
proxy_no_cache $http_cookie;
proxy_cache_bypass $http_cookie;
带cookie时不读不写缓存。
主动清除缓存
# 配置删除接口需要第三方模块或手动删目录
rm -rf /data/nginx/cache/*
更新内容后清对应目录,或按URL前缀匹配删除。
注意事项
- 缓存目录要先mkdir并给nginx读写权限;
- 带POST的接口不要缓存;
- 频繁变动的页面缓存时间设短或不缓存;
- 缓存键要带参数,避免不同query串内容;
- 配置改完nginx -t校验再reload;
- 大文件下载用分片缓存更稳妥。
总结
proxy_cache_path在http块定义缓存区,location里proxy_cache启用、proxy_cache_valid设有效期、proxy_cache_key拼缓存键,用X-Cache-Status看命中。静态和低频页面开缓存扛压力,动态登录内容用cookie绕过,更新后及时清理。
Nginx代理WebSocket Nginx
Nginx代理WebSocket
引言
聊天、实时推送、在线协作这类场景用WebSocket长连接。前端经过Nginx访问后端WS服务时,如果只按普通HTTP反代配置,握手会失败,因为WebSocket要先发起Upgrade协议升级,Nginx必须把升级头透传给后端。
WebSocket握手原理
客户端先发HTTP请求,带Upgrade: websocket和Connection: Upgrade头,后端同意后把HTTP协议升级成持久双向长连接。Nginx默认不透传这两个头,导致握手400。
标准代理配置
location /ws/ {
proxy_pass http://127.0.0.1:8080;
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;
}
- proxy_http_version 1.1:WS基于HTTP/1.1;
- Upgrade $http_upgrade:透传客户端升级协议;
- Connection "upgrade":标记连接升级;
- read_timeout拉长:长连接默认60秒无数据会被Nginx断开。
用map统一处理
不同location可能同时有HTTP和WS,写map避免硬编码:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# location内
proxy_set_header Connection $connection_upgrade;
普通HTTP请求$http_upgrade为空时走close,WS请求走upgrade,一套配置兼容。
常见问题
- 握手400/502:没加Upgrade和Connection头;
- 连接几十秒自动断开:read_timeout太短,按需拉长或服务端发心跳;
- wss(HTTPS)走Nginx终止TLS后,后端用ws即可;
- 后端端口和proxy_pass写对,别漏http://。
注意事项
- 长连接超时靠心跳和read_timeout共同维持;
- 集群WS要配合粘性会话或后端共享状态,否则消息发不到正确连接;
- HTTPS页面必须用wss://,浏览器会拦截混合内容;
- 改配置nginx -t后reload。
总结
Nginx代理WebSocket核心是加proxy_http_version 1.1、透传Upgrade和Connection头、拉长read_timeout,用map兼容普通HTTP。握手失败先查这三个头,断线先查超时和心跳。
Nginx静态缓存配置 Nginx
Nginx静态缓存配置
引言
CSS、JS、图片、字体这类不变的静态资源,每次都回源取一遍浪费带宽和时间。用Nginx给静态资源加浏览器缓存响应头,让浏览器本地留存,第二次访问直接读本地,首屏和重复访问速度明显提升。
配置示例
在server或location块中:
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff2?)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
参数说明
- expires 30d:设置缓存30天,浏览器本地留存;
- Cache-Control public:允许中间缓存(CDN、代理);
- immutable:文件内容不变,缓存期内不再发条件请求;
- access_log off:静态资源不记访问日志,减少IO。
带版本号更新
静态文件内容更新后,旧缓存会导致用户看到老文件。常用办法是文件名带哈希或版本,如app.[hash].js,内容一变文件名就变,浏览器当成新文件重新下载:
# 配合构建工具输出的带hash文件名,缓存可拉长到一年
expires 1y;
动态文件不要长缓存
HTML页面、接口响应要短缓存或不缓存,避免用户看到过期页面:
location / {
add_header Cache-Control "no-cache";
}
验证方法
浏览器F12网络面板看响应头:Cache-Control、Expires,再看状态码,二次访问200 from disk/memory cache即生效。
注意事项
- 缓存过期时间按资源稳定性设置,图片长、HTML短;
- 更新静态资源靠改文件名版本号,而不是缩短缓存;
- 不要给动态接口、登录页面加public长缓存;
- 改配置后nginx -t检查再reload。
总结
Nginx静态缓存用expires加Cache-Control给css/js/图片设置本地缓存,稳定资源配合版本号长缓存,动态页面不缓存。浏览器F12验证响应头,平衡访问速度与内容新鲜度。
Nginx开启Gzip压缩 Nginx
Nginx开启Gzip压缩
引言
HTML、CSS、JS、JSON这类文本资源直接传输体积大,首屏慢。Nginx开启Gzip后,服务端先压缩再发送,浏览器解压,通常文本体积能减少60%以上,是零成本提升访问速度的手段。
配置示例
在http块或server块加入:
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
参数说明
- gzip on:开关;
- gzip_min_length:小于1k不压缩,避免小文件压缩得不偿失;
- gzip_comp_level:压缩等级1-9,6比较均衡,太高CPU占用大;
- gzip_types:指定压缩的MIME类型,text/html默认自带;
- gzip_vary on:响应加Vary:Accept-Encoding,避免缓存问题;
- gzip_disable:兼容老旧IE浏览器。
生效验证
改完执行nginx -t检查语法,再reload。浏览器F12网络面板看响应头Content-Encoding:gzip即生效。
注意事项
- 图片、视频、PDF本身已压缩,不要再gzip,浪费CPU;
- 压缩等级不要盲目拉满,大文件压缩吃CPU;
- 静态资源可在CDN层提前压缩;
- 配合Brotli现代压缩效果更好,需Nginx额外模块支持。
总结
Gzip是文本类资源提速标配,开启后配置类型、大小阈值、合理压缩等级,reload生效,用响应头验证。不压缩图片视频,平衡传输体积与服务器CPU。
Nginx防盗链原理 Nginx
Nginx防盗链原理
引言
网站图片、视频、静态资源经常被其他站点直接引用,消耗服务器流量与带宽。Nginx防盗链通过校验请求来源Referer,阻止第三方网站直接嵌入你的资源链接,降低服务器流量损耗。
原理说明
浏览器访问页面加载图片时,请求头会携带Referer,代表来源页面地址。Nginx读取该请求头,判断域名是否属于本站,非信任域名直接返回403拒绝访问。
局限:Referer可被客户端伪造,防盗链属于基础防护,不是100%安全,重要资源建议搭配token鉴权。
Nginx配置示例
location ~* \.(jpg|png|gif|mp4)$ {
valid_referers none blocked *.0454.wang;
if ($invalid_referer) {
return 403;
}
}
配置解释:
valid_referers配置允许的来源;none允许直接浏览器地址栏访问资源;- 匹配不到白名单,
$invalid_referer生效,返回403。
进阶优化
- 重要资源可使用url签名,生成带时效token的资源地址;
- CDN环境,需要同步在CDN配置防盗链;
- 部分爬虫、APP请求不带Referer,按需调整规则。
总结
Nginx Referer防盗链是低成本的静态资源保护手段,适合图片博客、素材站点。适合作为第一层防护,高安全场景需要结合URL签名二次校验。
Nginx配置静态资源缓存,提升网站速度 Nginx
前言
每次访问网站都要重新下载图片、CSS、JS?太浪费了!配置Nginx静态资源缓存,让浏览器本地缓存这些文件,下次访问直接从本地读,速度快好几倍。
一、什么是浏览器缓存
浏览器访问网站后,把图片、CSS、JS等静态文件存在本地。下次再访问,直接从本地读,不用再从服务器下载。
好处:
- 加载更快
- 省带宽
- 减轻服务器压力
二、配置静态资源缓存
打开Nginx配置文件,在server段加:
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
参数解释
| 参数 | 含义 |
|---|---|
| expires 30d | 缓存30天 |
| expires 1h | 缓存1小时 |
| expires 1M | 缓存1个月 |
| Cache-Control public | 允许所有缓存 |
不同文件缓存时间
# 图片缓存30天
location ~* \.(png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
}
# CSS/JS缓存7天
location ~* \.(css|js)$ {
expires 7d;
}
# HTML不缓存(保证更新及时)
location ~* \.html$ {
expires -1;
}
三、验证配置
nginx -t
重载Nginx:
nginx -s reload
四、验证是否生效
方法1:curl测试
curl -I https://www.0454.wang/static/logo.png
看到响应头有:
Cache-Control: max-age=2592000
Expires: ...
就是生效了。
方法2:浏览器F12
按F12 → Network → 点图片请求 → 看Response Headers:
Cache-Control: max-age=2592000
五、缓存更新策略
问题: 缓存了30天,但我更新了图片怎么办?
方法1:文件名加版本号
<img src="/logo.png?v=20240101">
浏览器看到文件名变了,就会重新下载。
方法2:文件名加hash
<img src="/logo.abc123.png">
构建工具自动加hash,内容变了hash就变。
六、常见坑
坑1:HTML也被缓存了
问题: 更新了网站内容,但用户看到的还是旧的。
解决: HTML不缓存
location ~* \.html$ {
expires -1;
}
坑2:缓存时间太长
问题: 图片更新了,用户30天都看不到新的。
解决: 用版本号或hash。
坑3:CDN缓存了旧文件
问题: Nginx配置了,但CDN没刷新。
解决: 去CDN后台刷新缓存。
坑4:没加expires就没缓存
问题: 配置了但不生效。
检查: 看location有没有匹配到。
七、完整配置示例
server {
listen 80;
server_name www.0454.wang;
root /var/www/html;
# HTML不缓存
location ~* \.html$ {
expires -1;
}
# 图片缓存30天
location ~* \.(png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Cache-Control "public";
}
# CSS/JS缓存7天
location ~* \.(css|js)$ {
expires 7d;
add_header Cache-Control "public";
}
}
八、缓存时间怎么设
| 文件类型 | 推荐缓存时间 |
|---|---|
| 图片(png/jpg) | 30天 |
| CSS/JS | 7天 |
| HTML | 不缓存 |
| 字体文件 | 30天 |
九、怎么清除缓存
浏览器端
- 强制刷新:Ctrl + F5
- 清除浏览器缓存
服务器端
- 更新文件名版本号
- 重载Nginx
总结
记住:
- 静态资源加缓存,提升速度
- 图片缓存30天
- CSS/JS缓存7天
- HTML不缓存
- 更新了就改文件名版本号
- 用curl验证是否生效
最常用配置:
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Cache-Control "public";
}
遇到问题加QQ23979811 协助处理
Nginx配置Gzip压缩,提升网站加载速度 Nginx
前言
网站打开慢?带宽不够?开启Nginx的Gzip压缩,能把文件体积压缩70%以上,加载速度立马提升好几倍。本文讲怎么配置。
一、什么是Gzip
Gzip是一种压缩算法,Nginx在发给浏览器之前先把文件压缩,浏览器收到后自动解压。
效果:
- HTML/CSS/JS文件压缩70%左右
- 减少带宽
- 加载更快
二、配置Gzip
打开Nginx配置文件:
vi /etc/nginx/nginx.conf
在http段里加:
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
gzip_vary on;
gzip_buffers 16 8k;
gzip_http_version 1.1;
参数解释
| 参数 | 含义 |
|---|---|
| gzip on | 开启gzip |
| gzip_min_length 1k | 小于1k的文件不压缩 |
| gzip_comp_level 6 | 压缩级别1-9,6最合适 |
| gzip_types | 压缩哪些类型的文件 |
| gzip_vary on | 给响应头加Vary: Accept-Encoding |
| gzip_buffers | 压缩缓冲区 |
压缩级别说明
| 级别 | 效果 |
|---|---|
| 1 | 最快,压缩率最低 |
| 6 | 推荐,平衡 |
| 9 | 最慢,压缩率最高 |
推荐用6,不要用9,太吃CPU。
三、验证配置
nginx -t
重载Nginx:
nginx -s reload
四、验证是否生效
方法1:curl测试
curl -I -H "Accept-Encoding: gzip" https://www.0454.wang/
看到响应头有:
Content-Encoding: gzip
就是生效了。
方法2:浏览器F12
按F12打开开发者工具 → Network → 点请求 → 看Response Headers:
Content-Encoding: gzip
五、哪些文件该压缩
该压缩的
- HTML文件
- CSS文件
- JS文件
- JSON数据
- SVG图片
不该压缩的
- 图片(jpg/png):本身已经压缩过了
- 视频:太大,压缩没意义
- 压缩包(zip/rar):已经压缩过了
六、常见坑
坑1:只在http段配了,但server段覆盖了
检查: 看server段有没有gzip off。
坑2:gzip_types没写全
问题: JS文件没压缩。
解决: 加上application/javascript。
坑3:压缩级别太高
问题: 用了9,CPU飙升。
解决: 改成6。
坑4:CDN缓存了旧文件
问题: 配置了gzip但CDN没生效。
解决: 刷新CDN缓存。
七、完整配置示例
http {
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
gzip_vary on;
gzip_buffers 16 8k;
gzip_http_version 1.1;
server {
listen 80;
server_name www.0454.wang;
root /var/www/html;
index index.html;
}
}
八、对比效果
没开Gzip
HTML文件:100KB
开了Gzip
HTML文件:25KB
省了75%!
总结
记住:
- 开启gzip on
- 压缩级别用6
- gzip_types要写全
- 图片不要压缩
- 用curl验证是否生效
最常用配置:
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
gzip_vary on;
遇到问题加QQ23979811 协助处理