Nginx负载均衡配置,upstream多台服务器
前言
网站访问量上来了,一台服务器扛不住,想用多台服务器一起跑。Nginx 的负载均衡功能就是干这个的:前面一台 Nginx 当入口,后面多台服务器一起干活。
什么是负载均衡
用户请求 → Nginx(负载均衡)→ 服务器A
→ 服务器B
→ 服务器C
Nginx 把请求按规则分发到不同的后端服务器,分担压力。
基础配置
第一步:定义 upstream
在 http 块里定义后端服务器组:
upstream backend {
server 192.168.1.101:80;
server 192.168.1.102:80;
server 192.168.1.103:80;
}
第二步:反向代理到后端
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
负载均衡策略
轮询(默认)
默认就是轮询,一个一个轮流来。
upstream backend {
server 192.168.1.101;
server 192.168.1.102;
}
加权轮询
服务器性能不一样,性能好的多分点请求:
upstream backend {
server 192.168.1.101 weight=3;
server 192.168.1.102 weight=1;
}
意思是:每4个请求,3个给101,1个给102。
ip_hash
同一个用户的请求永远打到同一台服务器(解决 session 问题):
upstream backend {
ip_hash;
server 192.168.1.101;
server 192.168.1.102;
}
健康检查
某台服务器挂了,Nginx 自动把它踢出去:
upstream backend {
server 192.168.1.101 max_fails=3 fail_timeout=30s;
server 192.168.1.102 max_fails=3 fail_timeout=30s;
}
意思是:3次失败就暂停30秒不发请求给它。
完整配置示例
http {
upstream backend {
server 192.168.1.101 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.102 weight=1 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
常见坑
坑1:session 不一致
用户登录了,刷新一下又掉登录。
原因: 轮询把请求分到不同服务器,session 没共享。
解决: 用 ip_hash,或者用 Redis 统一存 session。
坑2:后端服务器改了但 Nginx 没生效
加了一台新服务器,配置也写了,但没重载。
解决: nginx -s reload。
坑3:后端服务端口不对
后端跑在 8080 端口,upstream 里写的 80。
解决: upstream 里写对端口。
坑4:后端获取不到真实 IP
后端日志里记的都是 Nginx 的 IP。
解决: 加 X-Forwarded-For 头:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
总结
负载均衡就两步:
- upstream 定义后端服务器列表
- proxy_pass 转发到 upstream
记住: 多台服务器用负载均衡,记得处理 session 共享问题。
遇到问题加QQ23979811 协助处理
Redis 缓存雪崩解决
Redis 缓存雪崩解决方案
缓存雪崩是 Redis 最常见的线上事故之一,搞懂怎么预防,关键时刻能救命。
1. 什么是缓存雪崩
大量缓存同时过期,或者 Redis 整个挂了,所有请求都打到数据库,数据库瞬间压力爆炸,直接崩溃。
就像雪崩一样,一层压一层,全完了。
2. 和缓存穿透、击穿的区别
穿透:查不存在的数据,缓存挡不住,一直打数据库。
击穿:一个热点 key 突然过期,瞬间大量请求打数据库。
雪崩:大量 key 同时过期,或者 Redis 挂了,整个数据库被打垮。
3. 解决方案一:过期时间加随机值
最常用的方法。不要所有 key 都设一样的过期时间,在基础时间上加随机数:
// 不好:所有 key 都 1 小时过期
$redis->setex('product:1', 3600, $data);
// 好:基础 1 小时,加 0-600 秒随机
$ttl = 3600 + rand(0, 600);
$redis->setex('product:1', $ttl, $data);
这样过期时间分散开,不会一起失效。
4. 解决方案二:热点数据永不过期
热点数据不要主动设过期,后台异步更新:
// 商品详情这种热点数据,不设过期
$redis->set('product:1', $data);
// 后台定时任务更新
// 不依赖过期时间,由程序控制刷新
5. 解决方案三:Redis 高可用
Redis 自己要高可用,不能单点:
- 主从架构 + 哨兵,主挂了自动切从
- Redis Cluster 集群,分片存储,一个节点挂了不影响全局
# Redis Sentinel 哨兵配置
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
6. 解决方案四:熔断降级
数据库撑不住的时候,要能自动降级:
- 限流:用令牌桶、漏桶算法,限制请求量
- 降级:返回默认数据或者"系统繁忙"
- 熔断:数据库连续报错多了,直接不访问数据库
常用工具:Sentinel、Hystrix。
7. 解决方案五:多级缓存
不要只靠 Redis 一层缓存:
用户请求 → 浏览器缓存 → CDN → Nginx 本地缓存 → Redis → 数据库
多级缓存,就算 Redis 挂了,前面还有 Nginx 缓存挡着。
8. 应急处理
真出问题了怎么办:
- 先限流,别让数据库被打死
- 恢复 Redis 服务
- 重新预热热点数据
- 慢慢放开流量
总结
缓存雪崩解决方案:
- 过期时间加随机值,别一起失效
- 热点数据永不过期,后台更新
- Redis 做高可用集群
- 加熔断限流兜底
- 多级缓存层层防护
记住这几点,缓存雪崩就不怕了。