应将静态资源处理拦截在Ingress层,通过ConfigMap配置proxy_cache_path、use_temp_path=off等参数启用Nginx缓存,并按资源类型设置cache_key与cache_valid,结合gzip压缩、Cache-Control响应头及X-Cache-Status监控确保缓存实效。

核心思路很明确:把静态资源的处理尽量“拦”在 Ingress 层,不让它穿透到后端服务。这不是加机器能解决的问题,而是架构层级的效率优化。
缓存必须配在 ConfigMap 里,不是靠注解
很多人误以为给 Ingress 加个 annotation 就能开启缓存,其实不行。Nginx 的缓存机制依赖底层存储区定义,必须通过 ingress-nginx-controller 的 ConfigMap 全局声明:
- proxy_cache_path 是前提:指定磁盘路径、目录层级(levels=1:2)、共享内存大小(keys_zone=static-cache:10m)、总容量上限(max_size=10g)和过期策略(inactive=60m)
- use_temp_path=off 要显式关闭:避免临时路径引发额外 IO 和锁竞争
- 配置写在 http-snippet 字段下,确保被注入到 nginx.conf 的 http 块顶层
缓存键和有效期得按资源类型分层控制
统一用 $request_uri 当缓存键容易出问题——比如带时间戳或用户 ID 的 JS 请求,会导致缓存碎片化。更稳妥的做法是:
- 对图片、字体、CSS、JS 等真正静态的资源,用 proxy_cache_key "$scheme$proxy_host$uri",忽略查询参数
- 用 proxy_cache_valid 区分状态码设有效期:200/302 缓存 1 小时,404 缓存 1 分钟,避免反复穿透
- 配合 Ingress 注解做路径级开关:nginx.ingress.kubernetes.io/configuration-snippet 中针对
\.(js|css|png|jpg|woff2)$正则启用缓存指令
别忘了压缩和响应头,这两项成本几乎为零
Gzip 压缩和 Cache-Control 响应头不消耗后端资源,却能直接减少传输体积、延长浏览器本地缓存时间:
- 在 ConfigMap 的 http-snippet 中开启 gzip:gzip on; gzip_types text/css application/javascript image/svg+xml;
- 用 add_header Cache-Control "public, max-age=31536000, immutable"; 告诉浏览器:这个文件一年内不会变,别再发 If-Modified-Since 了
- 加上 add_header X-Cache-Status $upstream_cache_status; 方便前端调试是否命中缓存
监控缓存是否真起效,只看三个指标
配完不验证等于没配。重点盯住:
- X-Cache-Status 响应头值:HIT / MISS / BYPASS —— 不是所有请求都该 HIT,但高频静态路径命中率应稳定在 85% 以上
- 后端 Pod 的 QPS:缓存生效后,相同资源请求量应断崖式下降,尤其对比 CDN 未接入时的 baseline
- Ingress Pod 的磁盘 I/O 和内存使用:/tmp/nginx_cache 目录占用应缓慢增长并趋于平稳,而不是持续飙升或清空


















