Nginx 不具备“API 切片缓存”能力,真实方案是微缓存(1秒缓存+proxy_cache_lock+proxy_cache_use_stale)配合精准缓存键与主动失效机制。

Nginx 本身不能把频繁变动的公共 API 接口“转化为每秒级高性能切片”——这个说法存在根本性误解。所谓“切片”不是缓存粒度的拆分,更不是对动态 API 做毫秒/秒级分段缓存。真实情况是:Nginx 没有“API 切片缓存”能力,也没有“按时间切片”的缓存机制。
你真正能做的,是对这类接口做微缓存(Microcaching)+ 精准失效控制,在极短窗口内复用响应,从而实现接近“每秒级复用”的效果。这和“切片”无关,而是靠时间精度、并发锁与状态头协同实现的。
✅ 微缓存:让高频变动 API 也能缓存 1 秒
适用于查询类接口(如实时行情、热搜榜、用户在线状态),数据每秒更新但客户端可接受最多 1 秒延迟。
location /api/trending {
proxy_pass http://backend;
proxy_cache api_cache;
proxy_cache_valid 200 302 1s; # 只缓存 1 秒
proxy_cache_use_stale updating; # 更新时仍返回旧缓存(避免雪崩)
proxy_cache_lock on; # 防止并发请求触发多次回源
add_header X-Cache-Status $upstream_cache_status;
}关键点:
-
proxy_cache_valid 1s是核心,不是“切片”,而是整个响应统一缓存 1 秒 -
proxy_cache_lock on保证同一 URI 在缓存过期瞬间,只放行一个请求去后端,其余等待并复用该响应 -
proxy_cache_use_stale updating让 Nginx 在后台更新缓存时,继续对外提供旧内容,消除抖动
✅ 区分请求维度:避免缓存污染
公共 API 常含参数(如 ?region=sh&limit=20),若不处理,不同参数会共用一个缓存 key,导致数据错乱。
proxy_cache_key "$scheme$request_method$host$uri$is_args$args";
# 或更安全:忽略无意义参数(如 utm_source、_t)
set $args_filtered "";
if ($args ~* "^(.*&)?(utm_[^&]+|_t=[^&]+)(&.*)?$") {
set $args_filtered "$1$3";
}
proxy_cache_key "$scheme$request_method$host$uri$is_args$args_filtered";这样可确保:
-
/api/trending?region=sh和/api/trending?region=bj缓存分离 -
/api/trending?region=sh&utm_source=web和/api/trending?region=sh共享缓存
✅ 主动失效:配合业务更新节奏
微缓存不能靠被动过期,需在数据变更时主动清理。Nginx 原生不支持 PURGE,但可通过以下方式:
-
用第三方模块(如 nginx-cache-purge):开放
PURGE方法 -
按 URL 模式清除(推荐):后端在更新数据后,调用
curl -X PURGE "https://api.example.com/api/trending*" -
用时间戳或版本号参数控制:让前端请求带
?v=2026061718,天然绕过旧缓存
❌ 不要误用 slice 模块
slice 指令只用于大文件(如视频)的 Range 请求代理拆分,对 JSON API 完全无效:
- 它不生成新缓存 key
- 不影响
proxy_cache行为 - 开启后反而可能因多次子请求触发重复回源或锁竞争
如果你看到“API 切片缓存”这类提法,大概率是混淆了 CDN 分片、客户端本地分片(如 SWR 的 key 分片)或后端服务的分片计算逻辑——这些都不在 Nginx 层实现。
Nginx 的角色很清晰:它不生产数据,也不理解业务语义;它只是高效地暂存、复用、转发已生成的响应。把 API “变成切片”这件事,得由上游服务设计(如按 region / time bucket 分接口),Nginx 只负责把这些接口的结果稳稳地缓存住、快速吐出去。



















