Apache可通过mod_maxminddb地理识别模块提取用户国家/城市代码,结合SetEnvIfExpr设置地域变量,再用<If>或mod_rewrite按变量将请求路由至不同balancer集群,实现地理位置智能分流。
apache 本身不支持直接根据用户地理位置做负载均衡决策,但可以结合地理 ip 解析模块(如 mod_maxminddb)+ 条件路由规则,把不同地域的请求提前分发到不同后端集群,从而实现“按地理位置智能分流”的效果。
关键不是让 mod_proxy_balancer 动态改权重,而是用地理信息做路由判断前置,再映射到已配置好、独立管理的 balancer 组。
✅ 必备前提:加载地理识别模块
推荐使用 mod_maxminddb(比旧版 mod_geoip2 更现代、维护活跃):
- 下载并编译安装
libmaxminddb和mod_maxminddb - 在 Apache 配置中加载:
LoadModule maxminddb_module modules/mod_maxminddb.so MaxMindDBEnable On MaxMindDBFile COUNTRY_DB /usr/share/GeoIP/GeoLite2-Country.mmdb MaxMindDBFile CITY_DB /usr/share/GeoIP/GeoLite2-City.mmdb
⚠️ 注意:需下载并放置对应
.mmdb文件(如 GeoLite2-Country),并确保路径和权限正确。
✅ 提取地域信息并设置环境变量
用 SetEnvIfExpr 或 RewriteCond 读取解析结果,例如:
# 提取国家代码(如 CN、US)
SetEnvIfExpr "%{env:MM_COUNTRY_CODE} == 'CN'" GEO_CN=1
SetEnvIfExpr "%{env:MM_COUNTRY_CODE} == 'US'" GEO_US=1
SetEnvIfExpr "%{env:MM_COUNTRY_CODE} == 'JP'" GEO_JP=1
# 提取城市(可选,用于更细粒度控制)
SetEnvIfExpr "%{env:MM_CITY_NAMES_EN} =~ m/^(Shanghai|Beijing|Shenzhen)$/" GEO_CHINA_MAIN=1这些变量后续可用于条件路由。
✅ 定义多个地域专属后端集群
每个集群可独立配置节点、权重、健康检查等:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
<Proxy balancer://cn-cluster>
BalancerMember http://cn-node1:8080 loadfactor=5
BalancerMember http://cn-node2:8080 loadfactor=3
ProxySet lbmethod=bybusyness timeout=5 retry=30
</Proxy>
<Proxy balancer://us-cluster>
BalancerMember http://us-node1:8080 loadfactor=4
BalancerMember http://us-node2:8080 loadfactor=4
ProxySet lbmethod=bytraffic timeout=8 retry=60
</Proxy>✅ 建议为不同地域集群启用不同
lbmethod或timeout,适配本地网络特征。
✅ 按地域变量做条件代理路由
在 <VirtualHost> 内,用 <If> 或 RewriteRule 实现精准转发:
方式一:用 <If>(推荐,Apache 2.4.13+)
<If "%{env:GEO_CN} == '1'">
ProxyPass "/" "balancer://cn-cluster/"
ProxyPassReverse "/" "balancer://cn-cluster/"
</If>
<ElseIf "%{env:GEO_US} == '1'">
ProxyPass "/" "balancer://us-cluster/"
ProxyPassReverse "/" "balancer://us-cluster/"
</Else>
# 默认兜底集群(如全球通用或新加坡节点)
ProxyPass "/" "balancer://global-cluster/"
ProxyPassReverse "/" "balancer://global-cluster/"
</If>方式二:用 mod_rewrite(兼容性更广)
RewriteEngine On
RewriteCond %{ENV:GEO_CN} =1
RewriteRule ^/(.*)$ http://cn-cluster/$1 [P,L]
RewriteCond %{ENV:GEO_US} =1
RewriteRule ^/(.*)$ http://us-cluster/$1 [P,L]
RewriteRule ^/(.*)$ http://global-cluster/$1 [P,L]⚠️ 注意:
[P]表示代理,[L]表示终止后续规则;所有 RewriteRule 应放在默认ProxyPass之前。
✅ 可选增强:地域+业务双维度分流
比如中国用户访问 /api/pay/ 走本地支付集群,而 /api/report/ 走中心报表集群:
<If "%{env:GEO_CN} == '1' && %{REQUEST_URI} =~ m#^/api/pay/#">
ProxyPass "/" "balancer://cn-pay/"
</If>
<If "%{env:GEO_CN} == '1' && %{REQUEST_URI} !~ m#^/api/pay/#">
ProxyPass "/" "balancer://cn-api/"
</If>这种组合能支撑灰度发布、合规隔离、CDN协同等复杂场景。
不复杂但容易忽略。核心就三步:装好地理库 → 提取地域标识 → 按标识路由到不同 balancer 组。不需要改后端逻辑,也不依赖外部服务,全在 Apache 层闭环完成。

















