在VPS上分步配置HAProxy负载均衡器

当网站或应用程序流量不断增长时,单一服务器往往无法承载所有请求。解决方案是部署多个后端服务器,并使用负载均衡器来分发传入流量。HAProxy是一款功能强大的开源负载均衡器和反向代理,能够处理数百万并发连接。它能自动检测不健康的服务器、智能分配流量、终止SSL连接,是构建可扩展高性能基础设施的理想选择。

为什么选择HAProxy而非Nginx

虽然Nginx和HAProxy都能进行负载均衡,但它们的设计理念不同。Nginx是一个通用型Web服务器,其中包含负载均衡功能。而HAProxy专门为流量管理和负载均衡设计。以下是HAProxy的优势:

前置条件

第一步 — 安装HAProxy

# 更新软件包列表
sudo apt update

# 安装HAProxy和Certbot(用于SSL管理)
sudo apt install -y haproxy certbot

# 验证安装
haproxy -v

应该看到HAProxy 2.x或更高版本。如果发行版提供的版本较旧,可从HAProxy PPA仓库添加最新稳定版本。

第二步 — 创建主配置文件

HAProxy的主配置文件位于/etc/haproxy/haproxy.cfg。先备份原始文件然后创建新配置:

sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.backup
sudo nano /etc/haproxy/haproxy.cfg

用以下综合的HAProxy配置替换内容:

global
  log stdout local0
  log stdout local1 notice
  chroot /var/lib/haproxy
  stats socket /run/haproxy/admin.sock mode 660 level admin
  stats timeout 30s
  user haproxy
  group haproxy
  daemon
  maxconn 262144              # 最大并发连接数

  # SSL安全配置(A+评级)
  ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
  ssl-default-bind-ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256

defaults
  log     global
  mode    http
  option  httplog
  option  denyall-on-abort
  timeout connect 5000
  timeout client  50000
  timeout server  50000
  retries 3

# 前端(接收客户端流量)
frontend myweb
  bind *:80
  bind *:443 ssl crt /etc/letsencrypt/live/domain.com/fullchain.pem key /etc/letsencrypt/live/domain.com/privkey.pem

  # 将HTTP重定向到HTTPS
  http-request redirect scheme https code 301 if !{ ssl_fc }

  # 设置表示HTTPS来源的头部
  http-request set-header X-Forwarded-Proto https if { ssl_fc }

  # 详细的HTTP日志
  option httplog

  # 捕获主机头用于调试
  capture request header Host len 64

  # 将所有流量路由到后端池
  default_backend webservers

# 后端(处理实际服务器上的流量)
backend webservers
  balance roundrobin                        # 分配算法

  # 健康检查
  option httpchk GET /health HTTP/1.1
  http-check expect status 200
  default-server inter 5s fall 2 rise 2

  # 定义后端服务器
  server backend1 192.168.1.10:8080 check   # 后端1的IP:端口
  server backend2 192.168.1.11:8080 check   # 后端2的IP:端口
  server backend3 192.168.1.12:8080 check   # 后端3的IP:端口

  # 通过Cookie的会话持久性
  cookie SERVERID insert indirect nocache
  server-template srv 1-10 0.0.0.0:80 disabled cookie srv

# 统计信息界面
listen stats
  bind *:8404
  stats enable
  stats uri /stats
  stats refresh 30s
  stats show-legends

必需的修改:

第三步 — 从Let's Encrypt获取SSL证书

在启动HAProxy前,需要使用Certbot获取SSL证书:

# 如果正在运行,先停止HAProxy
sudo systemctl stop haproxy

# 请求SSL证书(更改domain.com和email)
sudo certbot certonly --standalone -d domain.com -d www.domain.com --email [email protected]

# 根据提示进行响应

# 验证证书文件
ls -la /etc/letsencrypt/live/domain.com/

应该看到两个重要的文件:fullchain.pem(证书链)和privkey.pem(私钥)。

第四步 — 启动HAProxy服务

# 测试配置语法
sudo haproxy -c -f /etc/haproxy/haproxy.cfg

# 如果没有错误,启用并启动服务
sudo systemctl enable haproxy
sudo systemctl start haproxy

# 检查服务状态
sudo systemctl status haproxy

# 实时监控日志
sudo tail -f /var/log/haproxy.log

验证HAProxy运行:在浏览器中打开http://VPS_IP:8404/stats查看统计页面。会看到关于后端服务器的实时指标、请求计数和健康状态。

第五步 — 配置粘性会话

如果应用在服务器内存中存储会话数据,启用粘性会话将客户端路由到相同的后端:

# 编辑HAProxy配置
sudo nano /etc/haproxy/haproxy.cfg

# 在后端池中添加Cookie配置:
backend webservers
  balance roundrobin
  cookie SERVERID insert indirect nocache

  server backend1 192.168.1.10:8080 check cookie backend1
  server backend2 192.168.1.11:8080 check cookie backend2
  server backend3 192.168.1.12:8080 check cookie backend3

# 重新加载HAProxy以应用更改
sudo systemctl reload haproxy

HAProxy将在响应中注入名为SERVERID的Cookie。后续请求会使用此Cookie路由到同一后端。

第六步 — 设置自动SSL续期

SSL证书每90天过期。配置自动续期的post-renewal钩子:

# 创建续期钩子目录
sudo mkdir -p /etc/letsencrypt/renewal-hooks/post

# 创建续期钩子脚本
sudo nano /etc/letsencrypt/renewal-hooks/post/haproxy.sh

添加这个内容:

#!/bin/bash
# HAProxy SSL证书续期钩子
# 在证书续期成功后运行

# 使用新证书重新加载HAProxy
systemctl reload haproxy

# 可选:向管理员发送电子邮件通知
echo "HAProxy SSL证书已续期 $(date)" | mail -s "SSL已续期" [email protected]

保存然后赋予执行权限:

# 设置执行权限
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/haproxy.sh

# 测试续期dry-run(实际不更新)
sudo certbot renew --dry-run

# 自动续期通过cron定期运行

负载均衡算法

HAProxy在后端池中提供多种流量分配算法。修改balance设置:

1. 轮转法(Roundrobin,默认)

balance roundrobin
# 按顺序将请求发送给每个后端:srv1, srv2, srv3, srv1, srv2, ...

2. 最少连接

balance leastconn
# 路由到活跃连接数最少的后端
# 适用于长连接(如WebSocket或流媒体)

3. 源IP哈希

balance source
# 基于客户端IP哈希以一致地路由到同一后端
# 无需Cookie,但后端故障时会丢失会话数据

4. URI哈希

balance uri
# 基于请求URI进行路由,适用于基于内容的分布

高级健康检查配置

# 具有自定义时序的复杂健康检查
backend webservers
  # 每3秒检查一次,2秒超时
  # 3次失败标记服务器宕机,2次成功标记恢复
  option httpchk GET /health HTTP/1.1\r\nHost:\ domain.com
  default-server inter 3s fall 3 rise 2 timeout 2s

  server backend1 192.168.1.10:8080 check slowstart 60s
  server backend2 192.168.1.11:8080 check slowstart 60s
  server backend3 192.168.1.12:8080 check slowstart 60s

slowstart选项逐渐增加流量到恢复的新服务器,防止突发流量问题。

常见问题排除

HAProxy无法启动

# 检查配置语法错误
sudo haproxy -c -f /etc/haproxy/haproxy.cfg

# 常见问题:
# - 域名不匹配证书文件
# - SSL文件路径错误
# - 端口80/443已被其他服务占用

后端服务器未通过健康检查

# 手动测试后端连接
curl -v http://192.168.1.10:8080/health

# 检查防火墙是否阻止8080端口
sudo ufw allow 8080

# 或在云提供商中添加安全组规则

SSL证书无法正常工作

# 验证证书文件权限
sudo ls -la /etc/letsencrypt/live/domain.com/

# 赋予haproxy用户读取证书的权限
sudo chown -R haproxy:haproxy /etc/letsencrypt/live/domain.com/

# 重新加载HAProxy
sudo systemctl reload haproxy

监控和日志

实时统计信息

# 通过socket查询HAProxy统计
echo "show stats" | sudo socat stdio /run/haproxy/admin.sock | head -30

将日志转发到Syslog进行分析

# 安装rsyslog(如果未安装)
sudo apt install -y rsyslog

# 创建HAProxy特定的syslog配置
sudo nano /etc/rsyslog.d/99-haproxy.conf

添加这一行:

:programname, isequal, "haproxy" /var/log/haproxy/haproxy.log
& ~

重启rsyslog:

sudo systemctl restart rsyslog

HAProxy与其他负载均衡方案对比

功能 HAProxy Nginx AWS ALB
连接容量✅ 超100万并发✅ 10万+托管(无限制)
健康检查✅ 主动检查被动检查✅ 内置支持
粘性会话✅ Cookie方式✅ ip_hash模块✅ 目标粘性
SSL卸载✅ 完全支持✅ 完全支持✅ 完全支持
成本免费(开源)免费(开源)付费服务
设置复杂度中等(配置直观)中等(语法更简单)低(完全托管)
最适用场景高流量、复杂路由通用、较简单需求AWS生态、完全托管

需要用于部署HAProxy和后端服务器的可扩展VPS?

AsiaGB提供功能强大的Linux VPS,具有完整的根访问权限、SSD存储和99% 运行时间保证。完美用于部署可处理10万+ 并发连接的HAProxy负载均衡器。起价仅需 500 泰铢/月。

立即开始使用AsiaGB VPS

查看泰国VPS主机全部套餐 →