apache本身不重试请求,只做一次转发;所谓“重试”实为mod_proxy_balancer通过maxattempts≥2、failonstatus、retry、timeout和ping等参数实现的故障节点跳过与多节点轮询调度,本质是换后端再试,非同一服务重发。

Apache 本身不重试请求,它只做一次转发;所谓“分布式环境下的请求重试”,实际是通过 mod_proxy_balancer 实现的故障节点跳过 + 多节点轮询调度,本质是「换后端再试」,不是对同一服务重发请求。
必须启用负载均衡模块并配置基础调度逻辑
仅靠 ProxyPass 指向单个后端无法触发任何重试行为。要启用容错调度,需明确使用 balancer:// 协议,并确保以下模块已加载:
-
mod_proxy_balancer(核心,必须) -
mod_lbmethod_byrequests或mod_lbmethod_bytraffic(推荐byrequests,行为更可预测) -
mod_proxy_http(用于 HTTP 后端通信)
在配置中显式声明调度方式与尝试上限:
<proxy> BalancerMember http://node1:8080 BalancerMember http://node2:8080 ProxySet lbmethod=byrequests ProxySet maxattempts=2 ProxySet nofailover=Off </proxy>
其中 maxattempts=2 是关键——它表示单个客户端请求最多被分发给 2 个不同后端节点;设为 1(默认)等于完全禁用故障转移。
定义什么算失败:超时、错误码、健康探针三结合
不能只等连接断开才切换,分布式环境中常见慢响应、假存活、5xx 业务异常等场景,需多维度标记节点失效:
-
timeout=6:单次请求等待后端响应不超过 6 秒,超时即放弃当前节点,触发maxattempts换人 -
failonstatus=500-599:收到任意 5xx 响应后,立即将该节点标记为临时失效,进入冷却期 -
ping=5,HEAD,/health(Apache ≥2.4.33):每 5 秒主动探测健康接口,失败则本次请求跳过该节点(不改变其状态,也不计入retry)
每个 BalancerMember 应单独配置这些参数,例如:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
BalancerMember http://192.168.1.10:8080 timeout=6 retry=15 failonstatus=500-599 ping=5,HEAD,/health
retry=15 表示该节点被标记为失效后,15 秒内不参与新请求分发;超时后首次请求会试探性发送,成功则立即恢复,失败则继续隔离。
兜底降级:所有后端都不可用时返回友好页面
当全部节点处于 retry 冷却期或全部被标记为 DOWN 时,mod_proxy_balancer 默认返回 503 Service Unavailable。可通过 mod_rewrite 拦截并转向本地静态页:
RewriteCond %{ENV:REDIRECT_STATUS} ^503$
RewriteRule ^(.*)$ /offline.html [R=503,L]
确保 /offline.html 存在于 Apache 的 DocumentRoot 下,且不经过代理(即路径不匹配 ProxyPass 规则)。该方式不改变响应状态码,但提升终端用户体验。
验证是否生效的关键点
重试逻辑是否真正起作用,不能只看日志有没有报错,而要看请求是否实际打到了第二个节点:
- 检查后端访问日志:同一客户端 IP 的连续请求,应出现在不同节点日志中
- 观察响应头:
X-Balancer-Worker头会显示当前选中的后端标识(需开启ProxySet stickysession=none或确保无 session 粘性) - 手动模拟故障:临时停掉一个后端,发起请求,确认未返回 502/503,而是由另一节点正常响应
注意:该机制无法保证幂等性,对非幂等请求(如 POST 提交订单),需后端自行实现幂等控制,Apache 层不做重放语义保障。









