
当您的网站流量增长,单台服务器已无法承载所有传入请求——或者当那台服务器宕机并拖垮整个网站时,负载均衡器就是解决方案。它位于后端服务器前端,自动将传入请求分发到所有服务器,即使某台服务器故障,也能保持服务持续在线。
本指南将介绍什么是负载均衡器、如何选择算法,以及如何从零开始在Ubuntu VPS上将Nginx配置为负载均衡器。
前提条件:至少2台Ubuntu 20.04/22.04 VPS实例(1台负载均衡器 + 至少2台后端服务器),对所有服务器拥有SSH访问权限,并在所有服务器上安装了Nginx。
什么是负载均衡器?
负载均衡器是一种设备或软件,充当所有传入流量的单一入口点,然后根据所选算法将每个请求转发到多台后端服务器之一。用户始终连接到负载均衡器,而不是直接连接到后端服务器。
| 对比项 | 无负载均衡器 | 有负载均衡器 |
|---|---|---|
| 单点故障 | 存在——服务器宕机即网站下线 | 不存在——流量自动切换到健康服务器 |
| 流量承载能力 | 受限于单台服务器规格 | 分散到多台服务器 |
| 维护 | 必须使网站下线 | 下线一台服务器、部署、再重新加入 |
| 扩展方式 | 仅垂直扩展(升级配置) | 水平扩展(增加服务器数量) |
负载均衡算法
算法决定了负载均衡器如何决定将每个请求发送到哪台后端服务器。请根据您的工作负载进行选择:
1. 轮询算法(默认)
请求按顺序循环分发:A → B → C → A → B → C → … 当所有服务器配置相似且每个请求所需资源相近时效果最佳。
2. 最少连接算法
将每个新请求发送到当前活跃连接数最少的服务器。适用于长连接请求(如API调用、文件上传),部分请求耗时远长于其他请求的场景。
3. IP哈希算法
使用客户端IP地址决定将请求发送到哪台服务器。相同的IP始终路由到同一台服务器(会话持久性)。适用于将会话存储在服务器内存而非共享Redis或数据库的应用程序。
4. 加权轮询算法
带权重的轮询算法——配置较高的服务器接收更多请求。例如,服务器A(weight=3)处理每4个请求中的3个,服务器B(weight=1)处理每4个中的1个。
在Ubuntu VPS上搭建Nginx负载均衡器
Nginx原生支持负载均衡,无需额外软件。本示例使用3台VPS实例:
| 实例 | 角色 | 示例IP |
|---|---|---|
| VPS-LB | 负载均衡器(Nginx) | 10.0.0.1 |
| VPS-B1 | 后端服务器1(Web应用) | 10.0.0.2 |
| VPS-B2 | 后端服务器2(Web应用) | 10.0.0.3 |
步骤1 — 在负载均衡器上安装Nginx
SSH连接到VPS-LB并安装Nginx:
sudo apt update && sudo apt install nginx -y sudo systemctl enable nginx sudo systemctl start nginx
步骤2 — 创建upstream块
为负载均衡器创建新的站点配置文件:
sudo nano /etc/nginx/sites-available/load-balancer
粘贴以下内容(轮询为默认算法):
upstream backend_pool {
# Round Robin (default) — uncomment to change algorithm
# least_conn; ← Least Connections
# ip_hash; ← IP Hash (Session Persistence)
server 10.0.0.2:80;
server 10.0.0.3:80;
}
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
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_set_header X-Forwarded-Proto $scheme;
}
}为什么需要proxy_set_header?这些标头将真实客户端IP转发给后端服务器。如果没有这些标头,后端日志中每个请求只会显示负载均衡器的IP,使调试和数据分析毫无意义。
步骤3 — 启用配置
# Create symlink to enable sudo ln -s /etc/nginx/sites-available/load-balancer /etc/nginx/sites-enabled/ # Test configuration syntax sudo nginx -t # Reload Nginx (no downtime) sudo systemctl reload nginx
步骤4 — 使用加权轮询
如果VPS-B1的配置高于VPS-B2,可以为其分配更高权重以处理更多流量:
upstream backend_pool {
server 10.0.0.2:80 weight=3; # 处理每4个请求中的3个
server 10.0.0.3:80 weight=1; # 处理每4个请求中的1个
}步骤5 — 配置健康检查
Nginx可以检测后端服务器何时无响应,并暂时停止向其发送流量:
upstream backend_pool {
server 10.0.0.2:80 max_fails=3 fail_timeout=30s;
server 10.0.0.3:80 max_fails=3 fail_timeout=30s;
}| 选项 | 含义 |
|---|---|
| max_fails=3 | 连续3次健康检查失败后将该服务器标记为宕机 |
| fail_timeout=30s | 停止发送流量30秒后重试 |
添加proxy_next_upstream以实现更精细的被动健康检查:
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_set_header X-Forwarded-Proto $scheme;
# 如果后端返回错误,立即尝试下一台服务器
proxy_next_upstream error timeout http_502 http_503 http_504;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
}步骤6 — 为负载均衡器添加SSL
用户仅连接到负载均衡器,因此在此处安装SSL。后端服务器在私有网络上通过HTTP通信(SSL在负载均衡器处终止):
# 安装Certbot以使用Let's Encrypt
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.comCertbot会自动更新您的Nginx配置以处理HTTPS并设置自动续期。
SSL终止说明:当后端服务器位于同一数据中心的私有网络中时,这种在负载均衡器处解密HTTPS、然后转发HTTP到后端的方式是安全的。如果后端位于不同的地理位置,请改为使用端到端HTTPS。
步骤7 — 测试流量分配
在每台后端服务器上放置一个简单的测试脚本,以确认负载均衡器路由正常:
# 在VPS-B1上 echo '<?php echo "Response from: " . gethostname(); ?>' > /var/www/html/hostname.php # 在VPS-B2上 echo '<?php echo "Response from: " . gethostname(); ?>' > /var/www/html/hostname.php
然后从本地机器多次访问该接口:
for i in {1..6}; do curl -s http://yourdomain.com/hostname.php; echo; done您应该看到响应在vps-b1和vps-b2之间交替出现。
故障切换测试 — 让一台后端下线
# 停止VPS-B1上的Nginx以模拟服务器故障 sudo systemctl stop nginx # 您的网站应仍从VPS-B2正常响应 curl http://yourdomain.com/
预期结果:网站保持在线,由VPS-B2提供服务。Nginx根据max_fails设置检测到VPS-B1停止响应,并自动停止向其发送流量,直至其恢复。
无停机添加新后端服务器
要添加新的后端服务器,只需更新配置并重载Nginx——无需重启:
# 将VPS-B3加入服务器池 upstream backend_pool { server 10.0.0.2:80 max_fails=3 fail_timeout=30s; server 10.0.0.3:80 max_fails=3 fail_timeout=30s; server 10.0.0.4:80 max_fails=3 fail_timeout=30s; # ← 新服务器 } # 零停机重载 sudo nginx -t && sudo systemctl reload nginx
监控日志
# 实时查看访问日志 sudo tail -f /var/log/nginx/access.log # 查看错误日志 sudo tail -f /var/log/nginx/error.log
后续步骤:负载均衡器运行后,下一个挑战是共享状态。所有后端需要访问相同的会话(Redis)、相同的上传文件(NFS或对象存储)以及相同的数据库。建议使用Keepalived为负载均衡器本身添加高可用性,防止其成为新的单点故障。
启用Nginx状态模块进行实时监控
Nginx内置了stub_status模块,可提供实时连接统计信息。在负载均衡器的服务器配置中添加以下location块以安全启用该功能:
server {
listen 80;
server_name yourdomain.com;
location /nginx_status {
stub_status on;
allow 127.0.0.1; # 仅允许本地访问
allow 10.0.0.0/24; # 允许私有网络
deny all; # 阻止所有其他访问
}
location / {
proxy_pass http://backend_pool;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}重载Nginx后,查询状态接口:
curl http://localhost/nginx_status
典型响应如下:
Active connections: 45 server accepts handled requests 1024 1024 3891 Reading: 0 Writing: 3 Waiting: 42
| 字段 | 含义 |
|---|---|
| Active connections | 当前正在处理的连接总数 |
| accepts | 自Nginx启动以来接受的连接总数 |
| handled | 已处理的连接数(应与accepts相等) |
| Reading | 正在读取请求头 |
| Writing | 正在向客户端发送响应 |
| Waiting | 空闲的keep-alive连接,等待新请求 |
使用Redis共享会话存储解决会话问题
在现有Web应用程序中引入负载均衡器时,最常见的问题是会话不一致。用户登录后被路由到后端1,下一个请求却到达了不了解该会话的后端2,用户因此被强制退出登录。正确的解决方案是使用Redis作为所有后端服务器共同读写的会话存储中心。
安装Redis(在专用VPS或负载均衡器上)
sudo apt install redis-server -y sudo systemctl enable redis-server # 允许后端连接——编辑 /etc/redis/redis.conf # 修改:bind 127.0.0.1 → bind 127.0.0.1 10.0.0.1 sudo systemctl restart redis-server
在每台后端上配置PHP使用Redis会话
# 在每台后端上编辑 /etc/php/8.x/fpm/php.ini
session.save_handler = redis
session.save_path = "tcp://10.0.0.1:6379?auth=yourpassword"效果:用户只需登录一次,无论后续请求由哪台后端服务器处理,都能保持认证状态。使用共享Redis会话后,无需再使用IP哈希——轮询算法均衡分配负载,同时会话在整个服务器池中保持一致。
负载均衡器与反向代理——有何区别?
Nginx既可以充当反向代理,也可以充当负载均衡器。这两个术语相关但有所区别:
| 特性 | 反向代理 | 负载均衡器 |
|---|---|---|
| 主要用途 | 将请求转发到单台后端 | 将请求分发到多台后端 |
| 后端数量 | 通常为一台 | 两台或更多 |
| 故障切换 | 无——后端宕机即网站下线 | 自动——流量切换到健康服务器 |
| 主要优势 | SSL终止、缓存、压缩 | 高可用性、水平扩展能力 |
| Nginx配置 | proxy_pass http://127.0.0.1:3000 | upstream块 + proxy_pass |
实际上,Nginx的负载均衡器就是带有upstream服务器池的反向代理。两者的区别在于您代理到多少台后端以及是否涉及分发算法。
泰国与新加坡VPS的推荐架构
AsiaGB在泰国和新加坡均提供VPS,让您能够轻松构建多地区负载均衡设置,以低延迟服务东南亚的用户:
| 角色 | 推荐配置 | 起价 |
|---|---|---|
| 负载均衡器(LB) | 泰国VPS入门款——CPU占用低,仅处理路由 | 500泰铢/月 |
| 后端1(TH) | 泰国VPS——为本地用户提供低延迟 | 500泰铢/月 |
| 后端2(SG) | 新加坡VPS——覆盖东南亚及全球流量 | 500泰铢/月 |
多地区注意事项:当后端服务器跨越不同数据中心(泰国和新加坡)时,会话和数据库必须通过网络同步。建议使用Redis Cluster或MySQL主从复制,如果跨地区延迟导致会话同步延迟,可考虑使用IP哈希算法。