Apache mod_proxy_balancer本身不提供自动降级语义,但可通过retry、maxattempts、failonstatus组合实现故障转移,并配合mod_rewrite在全部后端不可用时跳转至兜底页面。

Apache 的 mod_proxy_balancer 本身不提供“自动降级”语义(如返回兜底页面、调用备用接口),但可通过组合配置实现请求重试 + 故障节点隔离 + 兜底跳转的近似效果。核心在于利用 retry、failonstatus、maxattempts 等参数控制重试行为,并配合 mod_rewrite 在全部后端不可用时转向静态资源。
启用基础重试与故障转移
重试不是无限循环,而是调度层的有限尝试。关键前提是启用支持重试的负载算法,并显式设置尝试次数:
-
必须配置
lbmethod=byrequests或bytraffic:这两个算法支持在当前 worker 失败后自动选下一个可用节点;bybusyness已废弃,不推荐 -
设
maxattempts=2:表示最多尝试 2 个不同后端节点;默认为 1(不重试),设为 2 即首次失败后自动转发给第二个健康节点 -
每个 BalancerMember 加
retry=15:节点失败后 15 秒内不参与调度,避免雪崩式重试;值应略大于后端典型恢复时间(如 Spring Boot Actuator 健康检查周期为 5s,设 15 合理) -
加
timeout=8:单次请求等待上限为 8 秒,超时即触发重试逻辑(需配合 maxattempts 才生效)
主动识别失败响应并触发剔除
仅靠连接超时无法覆盖业务异常,比如后端返回 503 但 TCP 连接正常。这时要用 failonstatus 主动标记失效:
-
failonstatus=500-599:收到任意 5xx 响应后,立即将该节点标记为失效,并进入 retry 冷却期 -
可叠加具体码:
failonstatus=500,502,503,504,更精准匹配网关类错误 - 注意:此判断发生在完整响应接收后,对连接中断、超时等场景无效,需和 timeout 配合使用
全部后端失效时跳转兜底页面
当所有节点都在 retry 期内或全部被标记为 DOWN,mod_proxy_balancer 会返回 503 Service Unavailable。此时可用 mod_rewrite 拦截该状态并重定向到本地静态页:
- 在
<location></location>或虚拟主机中添加: RewriteCond %{REQUEST_STATUS} ^503$RewriteRule ^(.*)$ /maintenance.html [R=503,L]- 确保
/maintenance.html存在于 DocumentRoot 下,且无需代理 - 该方式不改变响应码(仍为 503),但返回友好提示,属于最轻量的“降级”实践
健康检查增强(可选,提升感知精度)
如果 Apache 版本 ≥ 2.4.33,建议启用 proxy_hcheck 模块做前置探测,避免把请求发给已卡死但未断连的后端:
- 启用模块:
a2enmod proxy_hcheck(Debian/Ubuntu)或确认 LoadModule 已加载 - 为每个节点加:
hcmethod=HEAD hcuri=/health hcinterval=10 hcfailures=2 hctimeout=3 - 搭配自定义表达式:
ProxyHCExpr ok {%{REQUEST_STATUS} = 200},确保只认 200 为健康 - 注意:
hcuri必须指向后端真实健康端点(如/actuator/health),不能是 Apache 自身路径


















