Apache不支持动态增减节点,需通过外部机制生成配置并执行graceful重载实现平滑扩缩容:上线用DNS或脚本+独立配置+graceful;下线先drain再删除;必须启用mod_slotmem_shm、timeout/retry/loadfactor、stickysession及lbmethod=bybusyness。

Apache 本身不支持真正的“动态增减节点”,mod_proxy_balancer 也没有内置服务发现或实时配置热重载能力。所谓“在线平滑扩容”,本质是通过外部机制触发 Apache 配置更新并安全重载,整个过程对流量影响极小——不是零中断,但可做到无连接拒绝、无会话丢失。
核心思路是:把节点列表管理从静态配置中解耦,用可编程方式生成配置 + 安全重载
如何让新节点上线后立即承接流量
Apache 不会自动感知新服务实例,必须显式加入 BalancerMember 并重载配置。关键在于“如何加得快、加得稳”:
- 使用 DNS 名称代替 IP 列表(如
balancer://myapp/ http://app-svc.internal/),配合短 TTL(如 30 秒)和 Apache 的CacheEnable dns+CacheIgnoreNoLastMod on,让 mod_proxy 在 DNS 变更后逐步切换后端。但该方式无法控制权重、健康状态,仅适合简单场景。 - 更推荐做法:用脚本监听服务注册中心(如 Nacos/Etcd)变化,自动生成
<proxy></proxy>块内容,写入独立配置文件(如/etc/apache2/sites-enabled/balancer-dynamic.conf),再执行apache2ctl graceful。 -
graceful是关键:它启动新工作进程,等旧进程处理完现有请求后再退出,用户无感知;不中断长连接,不丢 session(尤其开启 stickysession 时)。
如何下线节点而不影响正在处理的请求
直接删掉 BalancerMember 并 reload,会导致已建立连接被强制断开。真正平滑下线需两步:
- 先标记节点为“禁用”而非删除:
BalancerMember http://192.168.1.10:8080 status=+D+D表示 drain(排空),Apache 将不再分发新请求给它,但允许其继续处理已有请求。 - 等待活跃连接自然结束(可通过
/balancer-manager页面观察Busy和Elected数值归零),再执行 reload 删除该行。
也可配合健康检查自动触发:BalancerMember http://192.168.1.10:8080 hcmethod=GET hcuri="/health" hcinterval=5 hcexpr="%{REQUEST_STATUS} == 200"
当健康检查连续失败,节点自动变为 down 状态,不再收新流量。
配置层面必须启用的关键选项
这些不是可选优化,而是平滑扩缩容的基础保障:
⚠️ 已弃用 — 该技能已拆分为两个独立技能,以提升模块化程度:**webchat-https-proxy**(HTTPS/WSS 反向代理)和 **webchat-voi...**
- 启用
mod_slotmem_shm:提供共享内存存储 balancer 状态,确保多进程间会话一致性。 - 每个
BalancerMember显式设置:timeout=5 retry=60—— 避免卡死在故障节点,60 秒后重试,期间不转发新请求。loadfactor=2—— 权重明确,扩容时可渐进调高,避免突增压力。route=server1+ProxySet stickysession=ROUTEID—— 保证 session 不因节点变更而漂移。 - 使用
lbmethod=bybusyness:比轮询更公平,新节点上线后不会因“空闲”而瞬间涌入大量请求。
管理界面与可观测性不能少
/balancer-manager 是运维眼睛,但默认禁用:
<Location "/balancer-manager">
SetHandler balancer-manager
Require ip 192.168.1.0/24
</Location>启用后可实时查看:
- 每个节点的
Busy、Elected、Status(Ok/Down/Draining) - 当前生效的
lbmethod和stickysession设置 - 手动启停单个节点(调试用,生产慎点)
注意:该页面依赖 mod_status,务必同时启用。
不复杂但容易忽略。

















