apache mod_proxy_balancer通过maxattempts=2、lbmethod=byrequests、timeout、failonstatus和retry等参数组合,实现请求级故障转移式重试(换节点再试),而非向同一后端重试;需配合ping探测与兜底降级策略。

Apache 的 mod_proxy 本身不提供“重试当前请求到同一后端”的语义,它不支持像 Nginx 的 proxy_next_upstream 那样在单次请求中自动换节点重试。但通过 mod_proxy_balancer 的组合参数,可以实现请求级故障转移式重试补偿——即:当一个后端失败时,自动尝试另一个健康节点,而非反复打向同一个坏节点。
关键不是“重试”,而是“换人再试”。这需要明确配置调度逻辑与失败判定边界。
一、启用基础负载均衡与重试前提
必须加载必要模块,并启用支持重试的调度算法:
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
在 <proxy></proxy> 中,强制指定调度方式并开启多尝试:
<proxy>
BalancerMember http://192.168.1.10:8080
BalancerMember http://192.168.1.11:8080
ProxySet lbmethod=byrequests
ProxySet maxattempts=2
ProxySet nofailover=Off
</proxy>
-
lbmethod=byrequests:轮询分发,是唯一支持maxattempts生效的算法(bytraffic也支持,bybusyness已废弃) -
maxattempts=2:表示最多尝试 2 个不同 worker;默认为 1(不重试) -
nofailover=Off:确保允许故障转移(默认即为 Off,显式写出更稳妥)
二、定义什么算“失败”:主动标记 + 超时控制
仅靠连接断开不够,需覆盖常见错误场景:
-
连接超时或响应异常 → 用
timeout和failonstatus -
后端卡死但 TCP 未断 → 需
ping探测(2.4.33+)
示例完整成员配置:
⚠️ 已弃用 — 该技能已拆分为两个独立技能,以提升模块化程度:**webchat-https-proxy**(HTTPS/WSS 反向代理)和 **webchat-voi...**
BalancerMember http://192.168.1.10:8080 \
timeout=5 \
retry=15 \
failonstatus=500-599 \
ping=5,HEAD,/health \
ping_timeout=2
说明:
-
timeout=5:单次请求代理等待上限为 5 秒,超时即放弃该 worker 并触发maxattempts换人 -
failonstatus=500-599:收到 5xx 响应后,立即将该 worker 标记为失效(进入retry=15冷却期) -
ping=5,HEAD,/health:每 5 秒对/health端点发 HEAD 请求;非 2xx 或超时(ping_timeout=2)则本次跳过该节点(不计入retry,只影响当次调度) -
retry=15:worker 失效后,15 秒内不参与任何新请求分发;到期后自动恢复试探
⚠️ 注意:
ping不是“健康检查心跳”,而是前置探测;它不改变节点长期状态,只用于本次请求是否可选。真正影响隔离周期的是retry和failonstatus/连接失败。
三、兜底降级:所有后端不可用时返回静态页
当 maxattempts=2 仍全部失败(即两个节点都处于 retry 期或永久离线),Apache 默认返回 503。可通过 mod_rewrite 捕获并降级:
# 启用重写引擎
RewriteEngine On
# 若 balancer 返回 503,且无可用后端,则重定向至本地维护页
RewriteCond %{ENV:REDIRECT_STATUS} ^503$
RewriteRule ^(.*)$ /maintenance.html [L]
确保 maintenance.html 存在于 DocumentRoot 下,并设置对应 MIME 类型(如 AddType text/html .html)。
也可用 ErrorDocument 503 /maintenance.html,但该方式不区分是否由 balancer 触发,适用性更广但粒度较粗。
四、验证与可观测性建议
- 访问
/balancer-manager(需mod_status启用且仅限内网)查看各 member 的状态、请求计数、失败次数、最后失败时间 - 开启
LogLevel proxy:debug可在 error_log 中看到 worker 选择、失败原因、重试动作等细节(生产环境慎用) - 不依赖 Apache 自身日志做告警,建议用外部工具(如 Prometheus + apache_exporter)采集
proxy_balancer_*指标,监控lbstatus、lbfactor、lbset变化趋势
不复杂但容易忽略










