Apache不支持原生主备语义,需通过mod_proxy_balancer配置权重(如loadfactor=10/1)、状态标记(status=+H/-H)及failonstatus、retry等参数实现故障自动转移与优先级调度。
启用必要模块并定义负载均衡器集群
apache 本身不直接支持“主备”语义,但可通过 mod_proxy_balancer 配置带权重和状态感知的后端组,实现自动故障转移。先确保以下模块已启用:
-
proxy、proxy_http(基础代理) -
proxy_balancer、lbmethod_byrequests(负载均衡必需) -
headers(可选,用于健康检查或请求头透传)
在 <VirtualHost> 或主配置中定义一个 balancer 组,明确指定主节点(高权重)和备节点(低权重或备用标记):
<Proxy balancer://myapp>
BalancerMember http://192.168.1.10:8080 loadfactor=10 status=+H
BalancerMember http://192.168.1.11:8080 loadfactor=1 status=-H
ProxySet lbmethod=byrequests
ProxySet failonstatus=500,502,503,504
ProxySet retry=15
</Proxy>
其中 status=+H 表示该成员默认禁用(仅当其他成员全不可用时才启用),status=-H 表示启用但不参与正常调度(需配合 loadfactor 和健康逻辑使用)。更稳妥的做法是用 loadfactor 控制优先级:主节点设为 10,备节点设为 1,Apache 会按比例分发请求,同时结合故障检测自动跳过失效节点。
配置故障感知与自动隔离机制
仅靠连接通断不足以判断服务是否真正可用,必须结合响应状态码和重试策略:
-
failonstatus=500,502,503,504:后端返回这些状态码即视为失败,立即标记该成员为 DOWN -
retry=15:节点被标记为 DOWN 后,15 秒内不再尝试调度,避免雪崩式探测 -
maxattempts=2:单次请求最多尝试两个成员,提升失败转移速度 - 推荐启用
proxy_hcheck(Apache 2.4.53+)做主动健康检查,例如:BalancerMember http://192.168.1.10:8080 hcmethod=HTTP hcinterval=10 hcuri=/health hcfail=3 hcpass=2
设置兜底路径与降级响应
当所有后端都处于不可用状态(包括主、备均失败或处于 retry 冷却期),Apache 默认返回 503。你可以拦截该状态,返回本地静态页面或降级接口:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
RewriteCond %{REQUEST_STATUS} ^503$
RewriteRule ^(.*)$ /offline.html [R=503,L]
确保 /offline.html 存放在 DocumentRoot 下,且不经过代理(即不匹配任何 ProxyPass 规则)。也可返回 JSON 格式兜底响应,适用于 API 场景:
<Location "/api/status">
SetHandler default-handler
Header always set Content-Type "application/json"
<IfModule mod_include.c>
Options +Includes
AddOutputFilter INCLUDES .json
</IfModule>
</Location>
配合一个简单的 status.json 文件,内容为 {"status":"degraded","message":"Service temporarily unavailable"}。
验证与运行时控制
通过 Apache 自带的 balancer-manager 页面(需显式启用)实时查看各节点状态:
<Location "/balancer-manager">
SetHandler balancer-manager
Require ip 127.0.0.1
Require ip 192.168.1.0/24
</Location>
还可结合 SetEnvIf 或自定义请求头动态开关主备行为。例如,收到 X-Force-Standby: true 时,强制将流量导向备机:
SetEnvIf X-Force-Standby "true" FORCE_STANDBY=1
<If "env('FORCE_STANDBY') == '1'">
ProxyPass / http://192.168.1.11:8080/
ProxyPassReverse / http://192.168.1.11:8080/
</If>

















