mod_cache_socache本身不支持基于地理位置变量做差异化缓存,它仅存储etag、过期时间等元数据,不参与缓存键生成;地理差异化需通过geoip2模块提取地区信息,结合vary头、cachekeybaseurl或url重写实现缓存键分离,mod_cache_socache仅在此基础上加速元数据查询。

mod_cache_socache 本身不支持基于地理位置变量(如 IP 归属地、X-Forwarded-For 地区头)做差异化缓存。它只负责在共享内存中存储元数据(ETag、过期时间、状态等),不参与缓存键(cache key)的生成逻辑,也不解析或响应地理信息字段。
缓存键由 mod_cache 决定,而它默认不识别地理变量
Apache 的缓存键默认基于请求 URL + Host + Accept-Encoding 等标准头生成。即使你启用了 mod_cache_socache,它只是把该键对应的元数据存进 shmcb,不会改变“哪些请求算同一个缓存项”这个根本规则。
若想按地区区分缓存,必须让不同地区的请求生成不同缓存键。可行路径有:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 用 mod_headers + mod_setenvif 提取地理信息(例如通过 GeoIP2 模块或反向代理传入的
X-Country: CN),再设置环境变量 - 用 CacheIgnoreURLSessionIdentifiers 配合自定义变量,但该指令仅忽略会话标识,不能主动注入新维度
- 更直接的方式:在响应前用 mod_rewrite 或 mod_macro 重写 URL,把地区码作为路径参数或子域名的一部分(如
/api/data?region=cn→/api/data-cn/),使天然形成不同缓存键
GeoIP2 是实现地理感知缓存的前提(非 mod_cache_socache 自带)
Apache 原生不解析 IP 地理位置。你需要额外模块,最常用的是 mod_geoip2(需安装 MaxMind GeoLite2 数据库):
- 启用后可获取
%{GEOIP_COUNTRY_CODE}e等变量 - 配合
SetEnvIfExpr把国家码设为环境变量:SetEnvIfExpr "%{GEOIP_COUNTRY_CODE} == 'US'" GEO_REGION=us - 再用
Header set X-Cache-Key "us-%{REQUEST_URI}e"辅助调试,但注意:header 不自动参与缓存键计算
真正起作用的是 CacheKeyBaseURL 或自定义 Vary 头
要让地区差异生效,核心是让 Apache 在生成缓存键时纳入地理维度。目前最可靠方式是:
- 显式设置 Vary 响应头,例如后端返回
Vary: X-Country,且确保请求中确实携带该头(由反向代理或 Lua 脚本注入) - 或使用第三方模块如 mod_cache_disk + mod_lua,在 cache key 计算前用 Lua 拼接地区标识(需 Apache ≥2.4.17 并启用 mod_lua)
-
CacheKeyBaseURL(Apache 2.4.51+)支持动态构造基础 URL,可嵌入环境变量:
CacheKeyBaseURL "https://example.com/%{GEO_REGION}e%{REQUEST_URI}e"
mod_cache_socache 在这里只起加速作用,不是决定因素
一旦你通过上述方式实现了多地区缓存键分离,mod_cache_socache 才能发挥价值:
- 为每个地区+URL 组合快速查元数据(是否过期、是否需 revalidate),避免反复读磁盘
- 高并发下减少对 mod_cache_disk 文件锁的竞争——尤其当同一地区大量用户请求相同资源时
- 注意:重启 Apache 后所有地区相关的元数据丢失,首波请求会全部 MISS,建议搭配较短的
CacheDefaultExpire和健康探测机制










