Nginx upstream负载均衡
当网站单台服务器扛不住流量时,用 Nginx 的 upstream 模块做负载均衡,把请求分给多台后端服务器,是最常见的分流方案。
下面从零开始,讲清楚怎么配置、怎么验证、怎么排错。
先确认环境和准备条件
动手前,确保满足以下条件:
- 一台安装好 Nginx 的服务器作为负载均衡器,系统可以是 CentOS、Ubuntu 或 Debian,Nginx 版本建议 1.18 以上。
- 至少两台后端 Web 服务器,已经部署好相同的网站程序,并且能独立访问。
- 负载均衡器能通过内网 IP 或公网 IP 访问到后端服务器的 Web 端口,通常是 80 或 8080。
- 后端服务器上的防火墙或安全组已放行对应端口。
登录负载均衡器,确认 Nginx 已安装并运行:
nginx -v
systemctl status nginx
如果未安装,在 CentOS 上可执行 yum install nginx -y,Ubuntu 上执行 apt install nginx -y。
配置 upstream 实现多服务器分流
Nginx 的负载均衡配置主要写在 http 块内。
找到主配置文件,通常在 /etc/nginx/nginx.conf,或者在 /etc/nginx/conf.d/ 下新建一个 .conf 文件。
下面是一个基本配置示例,把请求轮流分给两台后端服务器:
http {
upstream backend_servers {
server 192.168.1.101:80;
server 192.168.1.102:80;
}
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
关键点解释:
upstream backend_servers定义了一个服务器组,名字可以自定义。server指令列出后端服务器的 IP 和端口,默认采用轮询策略。proxy_pass指向这个 upstream 名称,Nginx 会自动把请求转发过去。- 添加
proxy_set_header是为了让后端能拿到真实客户端 IP 和域名。
保存后,测试配置并重载:
nginx -t
systemctl reload nginx
如果 nginx -t 报错,不要直接重启,先按提示修正语法。
调整分流策略与健康检查
默认轮询适合后端性能相近的场景。
如果服务器配置不同,可以按权重分配:
upstream backend_servers {
server 192.168.1.101:80 weight=3;
server 192.168.1.102:80 weight=1;
}
这样 101 收到的请求大约是 102 的 3 倍。
其他常用策略:
ip_hash;让同一 IP 的请求固定到同一台后端,适合有会话保持需求的场景。least_conn;把请求发给当前连接数最少的服务器。max_fails=2 fail_timeout=30s;表示在 30 秒内失败 2 次就暂时剔除该服务器,这是 Nginx 自带的被动健康检查。
加上健康检查的示例:
upstream backend_servers {
server 192.168.1.101:80 max_fails=2 fail_timeout=30s;
server 192.168.1.102:80 max_fails=2 fail_timeout=30s;
}
Nginx 开源版不支持主动健康检查,如果需要更精细的探测,可以考虑 Nginx Plus 或第三方模块,但多数场景用 max_fails 就够。
容易踩坑的地方
配置过程中有几个高频问题:
- 后端服务器返回 502 Bad Gateway:多半是后端 Web 服务没启动,或者防火墙拦截了负载均衡器的 IP。在负载均衡器上用
curl http://192.168.1.101测试能否直接访问。 - 后端收到的是负载均衡器的 IP 而不是用户真实 IP:检查是否漏了
proxy_set_header X-Real-IP $remote_addr;,同时后端程序要能读取这个头。 - 修改配置后没有生效:
reload不会中断连接,但配置必须通过nginx -t检查。如果报unknown directive,通常是 upstream 写在了server块里面,它必须放在http块内。 - 会话丢失:如果网站依赖本地 session,轮询会导致用户频繁重新登录。此时改用
ip_hash或把 session 存到 Redis 等共享存储。 - 权重设置不合理:低配服务器权重过高会拖慢整体响应,建议按实际压测结果调整。
验证分流是否生效
配置完成后,需要确认流量确实分到了多台后端。
方法一:在后端服务器的访问日志里观察。
分别登录 101 和 102,执行:
tail -f /var/log/nginx/access.log
然后用浏览器或 curl 多次访问负载均衡器的地址,看两台服务器的日志是否都有新记录。
方法二:在后端返回内容中加标记。
比如在 101 的网站根目录放一个 info.php 输出 "server 101",在 102 输出 "server 102",然后多次请求,观察返回内容是否交替出现。
方法三:临时停掉一台后端,比如 systemctl stop nginx,继续访问负载均衡器。
如果网站仍能正常打开,说明故障转移生效。
恢复后,该服务器会自动重新加入。
验证时建议用 curl -I 连续请求多次,快速查看响应状态和头信息。
常见疑问
upstream 里可以写域名吗?
可以,但 Nginx 只在启动时解析一次域名。如果后端 IP 会变,需要配置 resolver 并配合变量使用,否则重启 Nginx 才能生效。
负载均衡器本身挂了怎么办?
upstream 解决的是后端分流,负载均衡器仍是单点。生产环境通常用 Keepalived 做 VIP 漂移,或者直接使用云厂商的负载均衡服务。
需要修改后端服务器的 Nginx 配置吗?
后端服务器正常提供 Web 服务即可,不需要特别改动。但要确保后端能正确处理 X-Forwarded-For 头,否则日志里记录的可能是负载均衡器 IP。
支持 HTTPS 吗?
支持。可以在负载均衡器上配置 SSL 证书,然后 proxy_pass 到后端的 HTTP 端口;也可以直接代理到后端的 HTTPS 端口,但会增加一次加解密开销。
按以上步骤配置后,你的网站就具备了多服务器分流能力。
建议先在测试环境验证,再逐步切到生产流量。