Nginx proxy_cache共享内存区写满告警本质是keys_zone内存不足,而非磁盘空间不足;需检查keys_zone大小、proxy_cache_key是否发散、inactive与max_size配置是否失衡。

当 Nginx 出现 proxy_cache 共享内存区写满的告警(如 cache zone "xxx" is busy 或 no space in cache),本质是 proxy_cache_path 中定义的 keys_zone 内存区域不足以容纳当前缓存键(key)的元数据,而非磁盘空间不足。排查需聚焦内存结构、缓存键膨胀和配置匹配性。
确认告警来源和实际占用情况
先区分是真实内存耗尽,还是瞬时竞争导致的“busy”日志:
- 用
nginx -V 2>&1 | grep -o with-http-cache确认模块已启用 - 执行
curl -s http://127.0.0.1/nginx_status(需启用stub_status)或直接查ngx_http_proxy_module的共享内存状态(Nginx 1.19+ 可通过nginx -T | grep keys_zone配合ss -m | grep nginx粗略观察) - 更准确方式:在运行中执行
gdb -p $(cat /var/run/nginx.pid) -ex 'p ngx_cycle->shared_memory.nelts' -ex 'p ngx_cycle->shared_memory.elts' --batch(需调试符号),但生产环境慎用;推荐改用nginx -t -v查配置 + 日志频率判断是否高频触发
检查 keys_zone 内存大小是否合理
keys_zone 指定的是「仅存 key 和元数据」的共享内存,不存响应体。默认每条缓存项约占用 512 字节(含哈希桶、LRU 链、过期时间等)。若配置为 keys_zone=my_cache:10m,理论最多支持约 20,000 个不同 key:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
- 用
log_format记录$scheme$host$request_uri或$cache_key,采样分析实际 key 的分布和唯一性数量 - 特别注意带时间戳、随机参数(如
?t=123456789)、用户 ID、CSRF token 的请求——它们会让 key 失去可缓存性,快速撑爆 keys_zone - 若发现大量相似但参数不同的 URL(如分页、排序、设备标识),应在
proxy_cache_key中剔除无关变量,或用map统一归一化
验证 proxy_cache_key 是否过度发散
默认 key 是 $scheme$proxy_host$request_uri,看似安全,但实际易受 query string 波动影响。常见问题包括:
- 未显式定义
proxy_cache_key,导致客户端带跟踪参数(utm_*,ref=)生成无数变体 - 使用了
$request_uri(含 query)却没过滤参数;应改用$scheme$proxy_host$uri$is_args$args并配合map清洗 - 示例清洗:
map $args $clean_args { default ""; "~^(.*&)?utm_[^&]*(?:&.*)?$" "$1"; "~^(.*&)?ref=[^&]*(?:&.*)?$" "$1"; } proxy_cache_key "$scheme$host$uri$is_args$clean_args";
检查 inactive 和 max_size 是否协同失衡
inactive= 控制 key 元数据在内存中保留多久(无访问则淘汰),max_size= 控制磁盘缓存总量。二者不匹配会加剧 keys_zone 压力:
- 若
inactive=10m但大部分资源 TTL 是 1h,key 元数据可能早于内容被删,导致反复重建 key 结构,增加哈希冲突和内存碎片 - 若
max_size=1g但keys_zone=10m,意味着平均每个 key 对应 50KB 磁盘内容 —— 此时若大量小文件(如图标、JS)被缓存,key 数量会远超预期,应调高 keys_zone 或限制小文件缓存(proxy_cache_min_bytes) - 建议:keys_zone 容量 ≈ 预估峰值唯一 key 数 × 512B;inactive ≥ 最短业务缓存 TTL;max_size ≥ keys_zone × 100(经验值)

















