在多台后端服务器做负载均衡的场景中,如果每次请求都被随机分发到不同的机器,用户登录态、购物车数据就可能因为Session不一致而丢失。解决这个问题的常见手段之一就是源地址哈希负载均衡,即根据客户端的IP地址计算出一个哈希值,再把请求固定转发到某台后端服务器。Apache通过mod_proxy_balancer模块可以很方便地实现这种调度策略,下面我们从原理、配置和实践几个方面详细展开。

源地址哈希的工作原理
源地址哈希的核心思想很简单:对客户端IP地址执行一次哈希计算,然后用哈希结果对后端服务器数量取模或者映射到一个一致性哈希环上,从而确定这次请求应该交给哪台服务器。同一个客户端IP每次计算出的结果都相同,因此所有来自该IP的请求都会被发送到同一台后端节点,这就形成了所谓的会话粘性。
在Apache中,负载均衡功能由mod_proxy_balancer模块提供,调度策略则由不同的provider实现。Apache内置了lbmethod_byrequests(请求数加权轮询)、lbmethod_bytraffic(流量加权)、lbmethod_bybusyness(按繁忙度)和lbmethod_heartbeat(心跳检测)等算法。需要注意的是,标准的Apache发行版并没有直接提供一个名为source hash的lbmethod,源地址哈希的效果通常通过stickysession会话粘性机制,或者借助第三方模块(如基于mod_lbmethod_*的自定义模块)来实现。
哈希方式最大的特点在于它是无状态的。调度器不需要维护一张“哪个用户对应哪台服务器”的映射表,只要后端服务器列表不变,计算结果就是稳定的。这一点与基于Cookie的会话复制相比,减少了状态同步的开销,但代价是一旦后端节点数量发生变化,哈希取模的结果会大面积改变,用户的会话可能被打散。
Apache中的具体配置方法
要启用负载均衡,首先需要确认相关模块已经加载。以Linux环境下的Apache为例,通常需要启用mod_proxy、mod_proxy_balancer、mod_proxy_http以及mod_status(用于查看balancer-manager管理页面)这几个模块。可以通过a2enmod命令一次性启用,也可以直接在配置文件中去掉LoadModule指令前面的注释。
# 启用负载均衡相关模块 a2enmod proxy a2enmod proxy_balancer a2enmod proxy_http a2enmod lbmethod_byrequests systemctl restart apache2
接下来在虚拟主机或全局配置中定义balancer。下面的示例将两台Tomcat后端服务器加入名为mycluster的负载均衡组,并通过Header注入和stickysession参数实现基于源地址的请求粘性。stickysession指定了后端返回的SessionID参数名,Apache会依据该值把同一客户端固定到同一worker上,效果等同于源地址哈希。
<VirtualHost *:80>
ServerName www.ipipp.com
ProxyRequests Off
<Proxy balancer://mycluster>
BalancerMember http://192.168.1.101:8080 loadfactor=1
BalancerMember http://192.168.1.102:8080 loadfactor=1
ProxySet lbmethod=byrequests
ProxySet stickysession=JSESSIONID
</Proxy>
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
# 开启balancer管理页面(生产环境需限制访问)
<Location /balancer-manager>
SetHandler balancer-manager
Require ip 192.168.1.0/24
</Location>
</VirtualHost>
配置完成后建议先用apachectl configtest检查语法,再重启服务。访问http://127.0.0.1/balancer-manager可以看到每个worker的状态、请求数和错误计数,这在排查后端节点健康情况时非常有用。
如果希望更贴近真正的源地址哈希语义,还可以结合RewriteRule根据REMOTE_ADDR变量做映射,例如将不同网段的客户端定向到不同的balancer组,实现粗粒度的IP分流。这种方式适合按地域划分后端集群的架构。
RewriteEngine On
# 将192.168.10网段的请求路由到指定集群
RewriteCond %{REMOTE_ADDR} ^192\.168\.10\.
RewriteRule ^/(.*)$ balancer://mycluster/$1 [P,L]
源地址哈希与其他调度策略的对比
轮询(byrequests)是最简单的策略,请求依次分发给各个后端,适合后端性能相近、无状态的服务。加权轮询允许通过loadfactor参数给性能强的机器分配更多请求,灵活性更高。bybusyness则会把请求交给当前活跃连接最少的节点,对处理时长差异大的接口比较友好。
| 调度策略 | 会话保持 | 适用场景 | 主要缺点 |
|---|---|---|---|
| 轮询 byrequests | 无 | 无状态服务 | Session易丢失 |
| 源地址哈希/会话粘性 | 天然支持 | 有状态应用、缓存命中 | IP分布不均时负载倾斜 |
| bybusyness | 无 | 请求耗时差异大 | 需要准确统计连接数 |
源地址哈希的不足也很明显。第一,如果大量用户隐藏在同一个出口IP后面(比如企业内网或校园网通过NAT上网),所有请求都会压到同一台后端,造成严重的负载不均。第二,客户端IP是动态变化的场景,例如移动网络切换、拨号上网重新分配IP,用户的粘性会失效。第三,后端节点增减时哈希映射会重新分布,会话大量迁移。针对这些问题,建议采用分布式Session存储(如Redis集中管理Session)作为兜底方案,把哈希调度当作性能优化手段而不是唯一保障。
综合来看,源地址哈希类策略在缓存友好性和实现简单性上有明显优势,尤其适合后端节点数量稳定、用户IP分散的业务。实际部署时,建议同时配置热备节点,并通过balancer-manager持续观察各worker的负载情况,一旦发现某台机器请求占比异常,及时调整loadfactor或者切换到bybusyness策略,保证整个集群的稳定运行。
Apache负载均衡源地址哈希会话保持修改时间:2026-09-05 11:08:32