Apache需通过mod_proxy、mod_proxy_http、mod_proxy_balancer等模块实现负载均衡,生产环境须精细配置健康检查、会话保持与分层超时,禁用不安全的mod_proxy_ajp,避免仅依赖端口探测或简单sticky session。

Apache 本身不内置负载均衡能力,它需要通过 mod_proxy + mod_proxy_balancer 模块组合实现反向代理与负载分发。生产环境配置时,不能只写几行 ProxyPass 就上线——常见故障如会话丢失、健康检查失效、SSL 卸载异常、超时级联等,大多源于配置粒度不足或协议理解偏差。
必须启用的模块与基础结构
确认以下模块已加载(通常在 httpd.conf 或 mods-enabled/ 中):
-
mod_proxy(核心代理框架) -
mod_proxy_http(支持 HTTP/HTTPS 后端) -
mod_proxy_balancer(提供负载均衡调度逻辑) -
mod_ssl(如需 HTTPS 终止) -
mod_rewrite(用于路径重写、条件路由等增强控制)
禁用 mod_proxy_ajp 除非你明确使用 Tomcat AJP 协议——现代架构中 AJP 已逐步被 HTTP/2 或 gRPC 替代,且存在安全风险(如 CVE-2020-1938)。
后端健康检查不能依赖“能连通”
默认的 ping=5(每 5 秒 TCP 探测)仅验证端口可达,无法反映应用真实状态。生产环境必须配合 hcexpr 自定义 HTTP 健康探针:
<Proxy "balancer://myapp">
BalancerMember http://10.0.1.10:8080 route=app1 retry=60 timeout=5
BalancerMember http://10.0.1.11:8080 route=app2 retry=60 timeout=5
ProxySet lbmethod=byrequests
# 启用主动健康检查
ProxySet hcmethod=HEAD
ProxySet hcuri=/health
ProxySet hcinterval=10
ProxySet hcexpr="expr=%{REQUEST_STATUS} == 200 && %{RESPONSE_HEADERS} =~ /X-App-Status: ready/"
</Proxy>说明:
-
hcuri必须指向后端服务暴露的真实健康接口(建议返回轻量 JSON 或纯文本) -
hcexpr支持正则和表达式,可校验响应头、状态码、响应体内容,避免“端口通但应用卡死”的误判 - 不要把
/health设为重定向路径,否则HEAD请求可能失败
会话保持必须绑定到业务语义
简单用 stickysession=JSESSIONID 对 Spring Boot 应用可行,但对无状态微服务或 JWT 认证场景是反模式。正确做法分三类:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
-
有状态服务:用
route参数 + cookie 插入,确保同一用户始终落到同一实例 - 无状态服务:关闭 sticky,靠客户端 token 或 API 网关做一致性哈希路由(Apache 不适合做复杂路由决策)
- 混合场景:对登录、下单等关键路径启用 sticky;对静态资源、日志上报等路径禁用
示例(带 Cookie 路由):
<Proxy "balancer://auth">
BalancerMember http://auth1:8080 route=auth1
BalancerMember http://auth2:8080 route=auth2
ProxySet stickysession=ROUTEID
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; Path=/; HttpOnly; Secure" env=BALANCER_ROUTE_CHANGED
</Proxy>超时参数必须分层设置
Apache 的超时不是单个值,而是四层叠加,任一环节超时都会中断请求:
-
Timeout(全局连接空闲超时,默认 60s)→ 影响所有连接生命周期 -
ProxyTimeout(代理级响应等待,默认继承 Timeout)→ 控制从后端读响应的最大时间 -
ProxyBadHeader(默认 Ignore)→ 若后端返回非法头(如重复Content-Length),Apache 可能静默丢弃响应 - 每个
BalancerMember的timeout和retry→ 决定单次转发失败后的等待与重试策略
典型生产配置:
Timeout 30
ProxyTimeout 25
<Proxy "balancer://api">
BalancerMember http://api1:8000 timeout=20 retry=30
BalancerMember http://api2:8000 timeout=20 retry=30
ProxySet lbmethod=bybusyness
</Proxy>注意:timeout=20 是 Apache 等待该后端响应的上限,应略小于后端自身超时(如 Spring Boot 的 server.tomcat.connection-timeout=15000),避免出现“Apache 已断开,后端还在处理”的资源泄漏。
不复杂但容易忽略

















