mod_cache不能实现接口幂等性,它仅是HTTP层响应缓存机制,不校验请求唯一性、不处理重复提交,真正幂等性需在业务层通过Idempotency-Key+Redis等方案保障。

mod_cache 不能实现接口幂等性。它只做响应缓存,不处理请求唯一性、重复提交、状态变更冲突等问题。
幂等性是业务逻辑层的约束,而 mod_cache 是 HTTP 层的透明代理缓存机制 —— 它对 GET 请求缓存响应没问题,但对 POST、PUT、DELETE 等写操作默认不缓存(除非强行配置且绕过安全限制),更不会校验请求是否重复、是否已执行过。
下面分几个实际场景讲清楚怎么做、为什么不能靠 mod_cache、以及真正该用什么。
mod_cache 对 POST/PUT/DELETE 默认不缓存,强行开启风险极高
mod_cache 的设计初衷是加速「可安全重放」的只读请求,即符合 HTTP 幂等性定义的 GET、HEAD、OPTIONS。它默认忽略 POST,因为 RFC 明确规定 POST 不是幂等方法。
- 即使通过
CacheIgnoreNoLastMod On+CacheStorePrivate On+ 自定义CacheIgnoreHeaders强行让POST进入缓存,响应体可能被缓存,但下次相同请求进来时,mod_cache无法判断「这次 POST 是重试还是新操作」——它只比对 URL 和部分 header,不解析 body,也不查数据库或 Redis 记录 - 缓存的响应一旦返回,后端服务根本没执行,订单可能没创建、扣款可能没发生,造成业务逻辑断层
- 若后端返回了
Cache-Control: no-store或Set-Cookie,mod_cache会直接跳过缓存,你配得再细也无效
真正需要幂等性的接口,必须在业务代码里控制
比如用户下单、支付回调、库存扣减这类操作,核心是「同一请求只被执行一次」。这和缓存无关,而是要拦截、识别、去重。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 客户端必须携带幂等 key:
Idempotency-Keyheader 或idempotency_id参数,值为 UUID 或业务单号 - 服务端收到请求后,先查 Redis:
SETNX idempotency:{key} processing EX 300,成功则继续;失败说明已在处理或已完成 - 执行成功后,把结果(如订单号、状态)写入 Redis,设置合理过期时间(比如 24 小时),后续相同 key 直接返回缓存结果
- 不要依赖
mod_cache做这个事 —— 它没有原子写+读+过期联动能力,也无法保证「缓存写入」和「业务执行」的事务一致性
如果只是想减少重复 GET 请求压力,mod_cache 可以用,但要注意条件
对纯查询类 Restful 接口(如 GET /api/v1/users/{id}),mod_cache 能有效降低后端负载,但它不是「幂等性方案」,只是 HTTP 层性能优化。
- 确保后端返回明确的缓存头:
Cache-Control: public, max-age=60,否则mod_cache默认不缓存 - 避免在 URL 中拼接敏感参数(如
?token=xxx),否则 token 泄露且缓存键污染 - 如果接口返回内容依赖 header(如
Accept-Language),需用CacheIgnoreHeaders配合CacheKeyBase控制缓存键生成逻辑 - 磁盘缓存路径权限要正确,
mod_disk_cache的CacheRoot目录需 Apache 进程可读写,否则静默失败
Apache APISIX 的 proxy-cache 插件也不等于幂等性
虽然 proxy-cache 支持缓存 POST 响应(通过 allow_http_methods 配置),但它和 mod_cache 一样,只做「响应快照」,不感知业务语义。
- 它不会拒绝第二次相同的
POST,也不会记录「该请求已成功处理」 - 它无法区分「前端因超时重发的同一笔支付」和「用户手抖点了两次提交」
- 真要防重,仍需在 upstream 服务中用 Token + Redis 实现,网关层最多做透传或简单校验(如检查
Idempotency-Key是否缺失)

















