nginx缓存通过前置代理减少后端请求量,间接降低数据库压力;需配置proxy_cache_path定义缓存区、proxy_cache_key统一键值、proxy_ignore_headers避免set-cookie干扰、proxy_cache_lock防雪崩,并配合proxy_cache_use_stale与background_update提升容错性。

Nginx 缓存本身不直接查询数据库,但它能大幅减少打到后端应用(如 Python/Java 服务)的请求量,从而间接降低其对数据库的查询频次。关键在于:把缓存做在离用户更近、并发控制更强的位置,让多数请求根本不到达业务层。
配置缓存基础区域,让缓存有“地”可存
必须在 http 块中明确定义缓存路径和共享内存区:
-
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:512m inactive=3h use_temp_path=off;-
keys_zone是缓存元数据的“大脑”,名字(如my_cache)后续要被引用; -
use_temp_path=off很重要——避免临时文件拷贝,保证锁状态一致、响应更快; - 确保目录存在且 Nginx 进程有读写权限:
mkdir -p /var/cache/nginx && chown -R nginx:nginx /var/cache/nginx。
-
让缓存真正覆盖数据库压力源:动态 API 接口
数据库压力多来自 /api/user?id=123、/order/status?oid=abc 这类带参接口。默认按完整 URI 缓存,每个参数组合都是独立 key,导致缓存利用率极低,lock 也形同虚设。
应主动简化并统一缓存键:
- 若整个订单状态接口逻辑一致(不依赖用户身份),用:
proxy_cache_key "$scheme$host:/api/order/status"; - 若需保留路径但忽略参数顺序或无关参数(如
?t=123456),用:proxy_cache_key "$scheme$host$uri";
同时禁用干扰缓存的响应头:proxy_ignore_headers Set-Cookie Vary;
否则只要后端返回Set-Cookie,Nginx 默认跳过缓存,再好的配置也白搭。
启用 proxy_cache_lock,把并发回源压成串行
这是防“缓存雪崩”的核心机制:当大量用户同时访问一个已过期的热点接口时,Nginx 只放行第一个请求回源,其余等待复用结果。
需三者齐备:
-
proxy_cache my_cache;(启用缓存,没缓存 lock 不触发) -
proxy_cache_lock on; -
proxy_cache_lock_timeout 5s;(建议 3–8 秒:太短则等待请求放弃锁直接回源,失去意义;太长则用户明显卡顿)
加两道容错,避免单点失败拖垮全局
首个回源请求可能超时、报错或慢得离谱。不能让所有等待请求干等或全部穿透。
- 允许返回过期缓存:
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
即使锁持有者失败,等待请求也能立刻拿到旧内容,不卡、不穿、不断。 - 配合后台更新,让主响应快、缓存新:
proxy_cache_background_update on;
主请求返回 stale 内容的同时,后台悄悄刷新缓存,下次请求就用上新鲜数据。
后端配合:输出可缓存的响应头
Nginx 默认只缓存 200/302 等状态码,且要求响应含明确缓存指令:
- FastAPI 示例:
from fastapi import Response @app.get("/public/stats") def get_stats(): return Response( content='{"count": 123}', media_type="application/json", headers={"Cache-Control": "public, max-age=300"} ) - Flask 示例:
@app.route("/catalog/items") def catalog(): response = jsonify(items=get_cached_items()) response.headers["Cache-Control"] = "public, max-age=300" return response⚠️ 注意:别设
max-age=0或no-cache,这会让 Nginx 直接放弃缓存;也不要在登录态接口误加,需按路径分级控制。
不复杂但容易忽略











