要实现基于业务逻辑的精准缓存剔除,必须配合proxy_cache_bypass与proxy_no_cache构成读写双拦截,并用map统一提取登录态、角色、设备、路径、调试参数等信号生成0/1布尔变量,default全设为0以保默认缓存友好性。

proxy_no_cache 本身不跳过缓存查找,只控制响应是否写入缓存。要实现“基于业务逻辑的精准剔除”,必须配合 proxy_cache_bypass 构成读写双拦截,并用 map 提取真实业务信号生成可复用、可验证的布尔变量。
用 map 统一提取业务特征,避免硬编码
直接在 proxy_no_cache 中写正则或嵌套条件难以维护,也容易漏判。应将登录态、角色、设备、路径、调试参数等信号,全部转为 0/1 变量:
- 识别已登录用户:map $cookie_sessionid $no_cache_by_login { ~. 1; default 0; }(非空即视为有身份)
- 拦截高权限操作:map $http_x_user_role $no_cache_by_role { "admin" 1; "dev" 1; default 0; }
- 区分终端类型:map $http_user_agent $no_cache_by_ua { ~*Mobile 1; ~*WeChat 1; default 0; }
- 标记调试请求:map $args $no_cache_by_debug { ~debug=1 1; ~nocache=1 1; default 0; }
- 保护敏感路径:map $request_uri $no_cache_by_path { ~*^/api/v1/profile 1; ~*^/admin/ 1; default 0; }
location 中必须成对启用 bypass 和 no_cache
两个指令需传入完全相同的变量列表,Nginx 对它们的触发逻辑一致:任一变量值为 1,整条请求就全程脱离缓存链路。
- proxy_cache_bypass $no_cache_by_login $no_cache_by_role $no_cache_by_ua $no_cache_by_debug $no_cache_by_path; → 请求阶段跳过缓存查找,直连后端
- proxy_no_cache $no_cache_by_login $no_cache_by_role $no_cache_by_ua $no_cache_by_debug $no_cache_by_path; → 响应阶段禁止写入缓存,防止敏感内容残留
排除静态资源与匿名流量,守住默认缓存友好性
所有 map 的 default 必须设为 0,这是防止误伤的关键底线。未命中任何规则的请求,应自然走缓存流程。
- 不要在 http 块中全局写 proxy_no_cache $cookie_sessionid,空 cookie 会被当作非空字符串导致匿名用户也被绕过
- 对 /static/、/images/、.js、.css 等路径单独配置 location,跳过上述 map 判断,改用 expires 或 proxy_cache_valid 管理生命周期
- 若需灰度控制,可用自定义 header(如 X-Abtest-Flag),对应写 map $http_x_abtest_flag $no_cache_by_abtest { "on" 1; default 0; }
验证是否生效:看响应头 + 日志联动
配置后务必验证实际行为。在 server 或 location 块中加入:
- add_header X-Cache-Status $upstream_cache_status;(显示 HIT / MISS / BYPASS)
- log_format cache_log '$remote_addr - $request "$upstream_cache_status"';
发起带 sessionid 或 debug=1 的请求,确认响应头中 X-Cache-Status 显示为 BYPASS,且 access log 中对应字段也为 BYPASS,说明业务逻辑已精准生效。











