上篇回顾
上一篇我们讲了 HAProxy 的核心概念、五种负载均衡算法和热重载原理。这一篇聚焦两个运维中必须掌握的核心能力:健康检查 (确保请求只发给可用的后端)和 SSL 卸载(集中处理加解密,解放后端 CPU)。
第一部分:健康检查
一、为什么需要健康检查?
HAProxy 不知道后端服务器是否活着
→ 把请求发给宕机的后端
→ 用户收到 502 Bad Gateway
→ 需要健康检查来避免这种情况
健康检查的本质:HAProxy 定期探测后端服务器状态,自动将故障节点摘除,恢复后自动加入。
二、三种健康检查方式
1. TCP 检查(默认)--- 最快
haproxy
backend web-servers
server web1 127.0.0.1:9001 check
# 默认:每 2 秒检查一次 TCP 连接
# 失败 3 次标记为 DOWN
# 成功 2 次标记为 UP
检查过程:
HAProxy → 尝试 TCP 连接 web1:9001
连接成功 → 健康
连接失败 → 不健康
优点:快速,几乎无开销
缺点:只能检查端口是否在监听,不能检查服务是否正常
2. HTTP 检查 --- 最准确
haproxy
backend web-servers
mode http
# 发送 HTTP GET 请求到 /health
option httpchk GET /health
# 期望收到 200 状态码
http-check expect status 200
server web1 127.0.0.1:9001 check
检查过程:
HAProxy → 发 HTTP GET /health
后端返回 200 → 健康
后端返回 500 → 不健康
优点:能检查服务是否正常响应
缺点:比 TCP 检查稍慢,需要后端提供 /health 接口
3. 快速检查(Fast Check)--- 秒级切换
haproxy
backend web-servers
server web1 127.0.0.1:9001 check fall 1 rise 1
# fall 1:失败 1 次就标记为 DOWN
# rise 1:成功 1 次就标记为 UP
适用场景:需要快速切换的环境
能容忍少量误判的场景
对比:
fall 3 rise 2:3 次失败才判定,防误判(生产环境推荐)
fall 1 rise 1:1 次失败就判定,切换快(测试环境)
三、协议层检查
HAProxy 支持针对特定中间件的深度检查,不局限于 TCP 或 HTTP。
MySQL 检查
haproxy
backend mysql-servers
mode tcp
option mysql-check user haproxy_check
server mysql1 10.0.0.1:3306 check
Redis 检查
haproxy
backend redis-servers
mode tcp
option tcp-check
tcp-check send PING\r\n
tcp-check expect string +PONG
server redis1 10.0.0.1:6379 check
Elasticsearch 检查
haproxy
backend es-nodes
mode http
option httpchk GET /_cluster/health
http-check expect status 200
server es1 10.0.0.1:9200 check
协议检查对比
| 中间件 | 检查方式 | 检查什么 | 特点 |
|---|---|---|---|
| MySQL | mysql-check | 尝试 MySQL 协议登录 | 验证 MySQL 服务正常 |
| Redis | tcp-check PING/PONG | 发送 PING 期望 +PONG | 验证 Redis 响应正常 |
| Elasticsearch | HTTP /_cluster/health | 集群健康状态 200 | 验证集群可用 |
| etcd | HTTP /health | 返回 true | 验证 etcd 节点健康 |
四、参数详解
| 参数 | 默认值 | 说明 | 生产建议 |
|---|---|---|---|
| inter | 2000ms | 两次检查间隔 | 3s(不过于频繁,不浪费) |
| fall | 3 | 连续失败几次标记为 DOWN | 3(防网络抖动误判) |
| rise | 2 | 连续成功几次标记为 UP | 2(防刚恢复又挂) |
| timeout | 5000ms | 单次检查超时 | 5s |
生产环境推荐配置
haproxy
backend web-servers
server web1 127.0.0.1:9001 check inter 3s fall 3 rise 2
# inter 3s :每 3 秒检查一次(不频繁,不浪费)
# fall 3 :3 次失败才判定(防网络抖动)
# rise 2 :2 次成功才恢复(防刚恢复又挂)
第二部分:SSL 卸载
一、为什么需要 SSL 卸载?
没有 SSL 卸载时
客户端 后端服务器
── HTTPS 加密请求 ──→ 需要解密 → 消耗 CPU
←─ HTTPS 加密响应 ── 需要加密 → 消耗 CPU
每台后端都要做 SSL 加解密
证书管理复杂(每台都要配)
SSL 计算消耗大量 CPU
有 SSL 卸载时
客户端 HAProxy 后端服务器
── HTTPS ──→ 解密 → 明文请求 ──→ 不需要 SSL
←─ HTTPS ── 加密 ← 明文响应 不需要 SSL
↓
SSL 集中在 HAProxy 处理
后端只处理业务逻辑
证书只用配一份
二、三种模式
模式 1:SSL 卸载(HTTPS → HTTP)--- 最常用
客户端 HTTPS → HAProxy 解密 → HTTP → 后端
haproxy
frontend web-ssl-offload
# 监听 443,启用 SSL,指定证书
bind *:443 ssl crt /etc/haproxy/certs/demo.pem
mode http
default_backend web-http
backend web-http
mode http
server web1 127.0.0.1:9001 check
适用场景:后端服务不需要 HTTPS,SSL 全部在 HAProxy 终结。
模式 2:HTTP 跳转 HTTPS
客户端 HTTP → HAProxy 返回 301 → 客户端重定向到 HTTPS
haproxy
frontend web-http-redirect
bind *:80
mode http
# 所有 HTTP 请求都重定向到 HTTPS
redirect scheme https code 301
模式 3:双向 SSL(HTTPS → HTTPS)--- 全链路加密
客户端 HTTPS → HAProxy 解密 → 重新加密 → HTTPS → 后端
haproxy
frontend web-bidir-ssl
bind *:443 ssl crt /etc/haproxy/certs/demo.pem
mode http
default_backend web-ssl-backend
backend web-ssl-backend
mode http
# 转发到后端时也启用 SSL
server web1 127.0.0.1:9443 ssl verify none check
适用场景:安全要求极高,内网也必须加密传输。
三种模式对比
| 模式 | 客户端→HAProxy | HAProxy→后端 | 适用场景 |
|---|---|---|---|
| SSL 卸载 | HTTPS | HTTP | 大多数 Web 服务,性能优先 |
| HTTP 跳转 | HTTP→HTTPS | --- | 强制 HTTPS 访问 |
| 双向 SSL | HTTPS | HTTPS | 金融/合规场景,全链路加密 |
三、证书准备
自签名证书(测试环境)
bash
# 生成私钥和证书
openssl req -x509 -newkey rsa:2048 -nodes -days 365 \
-keyout demo.key -out demo.crt \
-subj "/CN=haproxy-demo.local"
# 合并成 HAProxy 需要的 PEM 格式
cat demo.crt demo.key > demo.pem
# 放到 HAProxy 配置目录
mkdir -p /etc/haproxy/certs/
cp demo.pem /etc/haproxy/certs/
生产环境证书
bash
# 生产环境证书(从 CA 获取)
# 合并证书 + 私钥 + 中间证书链
cat yourdomain.crt yourdomain.key ca-chain.crt > yourdomain.pem
重要 :HAProxy 要求证书和私钥在同一个 PEM 文件中,顺序为:服务器证书 → 私钥 → CA 中间证书链。
四、透传客户端信息
SSL 卸载后,HAProxy 到后端是明文 HTTP,后端丢失了客户端真实 IP 和 SSL 信息。需要通过 header 透传:
haproxy
backend web-http
mode http
# 传递客户端真实 IP
option forwardfor
# 传递 SSL 协议版本
http-request set-header X-Forwarded-Proto https
# 传递 SSL 加密套件
http-request set-header X-SSL-Protocol %[ssl_fc_protocol]
http-request set-header X-SSL-Cipher %[ssl_fc_cipher]
server web1 127.0.0.1:9001 check
五、验证 SSL 卸载
bash
# 验证 HTTPS 访问
curl -k https://127.0.0.1:443/
# 返回内容,说明 SSL 卸载成功
# 查看 SSL 版本
curl -kv https://127.0.0.1:443/ 2>&1 | grep "SSL connection"
# TLSv1.3, AES_256_GCM
# 验证 HTTP 跳转
curl -I http://127.0.0.1:80/
# HTTP/1.1 301 Moved Permanently
# Location: https://127.0.0.1/
本期总结
健康检查:
- TCP 检查最快,HTTP 检查最准确,协议层检查最专业
fall 3 rise 2是生产环境标准配置,防误判- 不同中间件有特定的检查方式(MySQL/Redis/ES)
SSL 卸载:
- 核心思想:SSL 集中处理,后端只做业务
- 三种模式:卸载(HTTPS→HTTP)、跳转(HTTP→HTTPS)、双向(HTTPS→HTTPS)
option forwardfor透传客户端真实 IP- 证书格式:PEM(证书 + 私钥 + 中间链合并)