apache本身不主动探测后端健康状态,必须启用mod_proxy_hcheck模块(2.4.33+),配置hcmethod、hcuri、hcinterval等参数实现主动探测,并结合proxyhcexpr自定义健康判定逻辑,辅以retry、failonstatus等被动策略,才能实现故障节点的自动检测与恢复。

必须加载并启用健康检查模块
Apache 2.4.33+ 才支持真正的主动健康检查,需确保以下模块已启用:
- mod_proxy_balancer:提供负载均衡基础能力
- mod_proxy_hcheck:实现周期性 HTTP 探测(核心)
- mod_status:支撑 balancer-manager 管理界面(调试必需)
Debian/Ubuntu 运行:a2enmod proxy proxy_http proxy_balancer proxy_hcheck status;RHEL/CentOS 检查 /etc/httpd/conf.modules.d/00-proxy.conf 中对应 LoadModule 行是否取消注释。
配置主动健康检查参数
在 <proxy balancer:></proxy> 块中为每个后端明确设置探测规则:
- hcmethod=HEAD 或 hcmethod=HTTP:推荐 HEAD,轻量无副作用
-
hcuri=/health:必须指向后端真实暴露的健康端点(如 Spring Boot 的
/actuator/health),不能是 Apache 自身路径 - hcinterval=10:每 10 秒探测一次(不宜过短,避免压垮后端)
- hcfail=3:连续 3 次失败才标记为 DOWN(设为 1 易受网络抖动误判)
- hcpass=2:连续 2 次成功才恢复为 UP(避免刚返回 200 就转发流量,业务尚未就绪)
示例:
BalancerMember http://192.168.1.10:8080 hcmethod=HEAD hcuri=/health hcinterval=10 hcfail=3 hcpass=2
BalancerMember http://192.168.1.11:8080 hcmethod=HEAD hcuri=/health hcinterval=10 hcfail=3 hcpass=2
定义健康判定逻辑(关键!)
仅靠状态码匹配不够。默认情况下,5xx 响应不会触发下线。必须用 ProxyHCExpr 自定义判断条件:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- ProxyHCExpr ok {%{REQUEST_STATUS} =~ /^[23]/}:把 2xx 和 3xx 都视为健康
- 若后端健康接口返回 JSON 且含
"status":"UP",可配合mod_ssl和正则提取:ProxyHCExpr ok {%{hc_resp_body} =~ /"status"\s*:\s*"UP"/} - 该表达式需放在全局或
<proxy></proxy>块内,且名称(如ok)需与hceval=ok对应
完整示例片段:
ProxyHCExpr ok {%{REQUEST_STATUS} =~ /^[23]/}BalancerMember http://192.168.1.10:8080 hceval=ok ...
补全被动容错与恢复兜底
主动检查可能漏掉“假活”节点(进程卡死但 TCP 不断)。需叠加被动策略:
- retry=60:节点被标记为 DOWN 后,60 秒内不参与调度(单位秒,非重试次数)
- failonstatus=500-599:实际请求返回 5xx 时立即计为一次失败,加速剔除
- timeout=5:单次请求超时设为 5 秒,防止长阻塞拖慢整体
-
maxattempts=2:配合
lbmethod=byrequests,允许单次请求最多尝试两个节点
这些参数写在 BalancerMember 行末尾即可,例如:
BalancerMember http://192.168.1.10:8080 retry=60 failonstatus=500-599 timeout=5
验证与调试不能只看页面
balancer-manager 页面显示的 UP/DOWN 是最终状态,不反映实时探测过程。真正的问题藏在日志里:
- 开启详细日志:
LogLevel proxy_hcheck:trace8 - 在
error_log中搜索hcheck,确认是否发出请求、收到什么响应、耗时多少 - 手动测试后端健康端点:
curl -I http://192.168.1.10:8080/health,确保返回 200 且无延迟 - 检查防火墙、SELinux 是否拦截了 Apache 主动发起的探测请求










