一台VPS撑不住了——CPU跑满、带宽打满、偶尔502。这时候加配置是一条路,但单机的上限摆在那里。更灵活的做法是加机器做负载均衡:多台VPS分担流量,一台挂了其他继续服务。本文用Nginx反向代理搭建一个最基础的负载均衡方案,三台后端服务器加一台前端负载均衡器。
负载均衡解决什么问题
单台VPS有四个天花板:CPU算力、内存容量、带宽上限、单点故障。前三个可以通过升级配置解决,但越往上性价比越低——1核2G升级到2核4G价格翻倍,性能未必翻倍。第四个(单点故障)升级配置也解决不了——服务器挂了就是挂了。
加机器做负载均衡的思路是:用一台VPS作为入口(负载均衡器),把用户请求分发到后面多台VPS上。每台后端VPS配置可以很低——三台1核1G的便宜机器加起来不如一台4核8G贵,但三台能扛的并发量可能超过那一台。
准备四台VPS
需要用四台VPS来搭这个方案:
- 负载均衡器(前端Nginx):1核1G够用,它只转发不处理业务逻辑。可以是最便宜的入门配置。
- 后端服务器×3:每台部署完全相同的网站代码和数据库(或者数据库独立一台)。配置按正常业务需求来。
省钱方案:后端用雨云的入门KVM,优惠码 admin01 首月五折。三台后端加一台前端,月总成本可以压到30元以内。
第一步:部署三台后端服务器
每台后端服务器上安装好Nginx(或你用的Web服务器),部署完全一样的网站代码。确认每台后端能独立正常访问——在浏览器直接输入后端服务器的IP,网站应该能打开。
如果网站有数据库,这里有两个选择:集中式数据库(一台独立的数据库服务器)和分布式数据库(每台后端配自己的数据库+主从同步)。集中式最简单——负载均衡器只转发HTTP请求,数据库连接由后端自己处理,都指向同一台数据库。
第二步:配置前端Nginx做反向代理和负载均衡
在前端VPS上编辑Nginx配置文件:
# /etc/nginx/conf.d/load_balancer.conf
upstream backend_pool {
# 默认轮询,请求按顺序分给三台后端
server 10.0.1.1:80 weight=1; # 后端1
server 10.0.1.2:80 weight=1; # 后端2
server 10.0.1.3:80 weight=1; # 后端3
# 健康检查:如果后端连续2次请求失败,暂时踢出
# 注:需要安装nginx-mod-stream模块
}
server {
listen 80;
server_name 你的域名;
location / {
proxy_pass http://backend_pool;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 超时设置
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
}
}weight参数控制分配权重——weight=3的后端会收到三倍于weight=1的请求。如果三台后端配置不同,给配置高的加权重。
第三步:选择分配策略
Nginx 默认是轮询(Round Robin),还有几种策略可以按业务需求选:
| 策略 | 配置 | 什么时候用 |
|---|---|---|
| 轮询(默认) | 不加额外参数 | 后端配置相同 |
| 加权轮询 | 加 weight=值 | 后端配置不同 |
| IP哈希 | 加 ip_hash | 需要同一用户的请求始终发同一台后端(有登录态时) |
| 最少连接 | 加 least_conn | 请求处理时间差异大(有的快有的慢) |
如果你的网站需要用户登录,用IP哈希——同一个IP的请求始终转发到同一台后端,避免用户在后端A登录了、下一个请求转发到后端B发现没登录。缺点是如果用户IP变了(移动网络切基站),就会跳到另一台后端。
第四步:解决Session共享
如果不用IP哈希、用户请求可能分散到不同后端,就会遇到Session问题——用户在后端A登录,下一次请求发到后端B,后端B不知道他是谁。
三种解决方案:
- 用IP哈希(最简单,上面说了)
- 用Redis存Session:所有后端读写同一个Redis实例。PHP配置session.save_handler=redis,所有后端的用户状态统一存Redis。这是最常用的方案。
- 用JWT代替Session:把用户信息编码进token里,客户端每次请求带token,后端不需要查Session。更轻量,适合API服务。
第五步:健康检查和故障转移
负载均衡最有价值的能力不是分流,是自动踢掉挂了的后端、流量转发到还能用的后端。
Nginx Plus 有内置的健康检查,开源版需要装 nginx-upstream-check-module 或自己在前面加一层 keepalived+haproxy。简单场景下,Nginx 的被动健康检查够用——如果某个后端连续几次返回5xx或超时,Nginx会暂时把它摘掉。
测试方法:手动停掉一台后端的Nginx(systemctl stop nginx),刷新前端页面,应该还能正常打开——因为Nginx自动把请求转给了另外两台。
局限性
这套方案有一个单点:前端那台Nginx负载均衡器。如果它挂了,全部后端都不可达。解决方案是给前端也做高可用——用Keepalived在两台前端之间做VIP漂移。但那属于进阶方案,小型项目前端一台够用,挂了手动切备用。
另外,如果后端之间的数据库不同步(每台后端有自己的数据库),用户可能在不同请求中看到不同版本的数据。数据库要么集中一台、要么做主从复制——别让每台后端各写各的。
常见问题
三台1核1G的小机器和一台4核4G的大机器哪个好?
并发能力上,三台小机器通常更强——因为Nginx和PHP等进程在三台机器上并行跑,总CPU时间更多。但数据库场景例外——如果数据库是大头,单台高配机器的一块大内存比三台小机器各自小内存好用。评估瓶颈在哪里再决定。
后端服务器可以跨机房吗?
技术上可以,但数据库延迟会拖垮性能。如果后端A在洛杉矶、后端B在法兰克福、数据库在洛杉矶,后端B每查一次数据库就要走跨大西洋延迟。建议后端和数据库在同一个机房、同一个内网。
CDN和负载均衡有什么区别?
CDN是静态内容缓存和就近分发(你不需要自己搭服务器),负载均衡是动态请求分发(你自己管服务器)。两者互补——CDN扛住图片/JS/CSS这类静态文件,负载均衡扛住动态的PHP/API请求。






