Nginx 中 fastcgi_cache_key 如何定义唯一的缓存键值

作者:袖梨 2026-07-14
定义唯一的 fastcgi_cache_key 需明确“哪些请求该共享同一份缓存”,核心必须包含 $scheme、$request_method、$host、$request_uri,并按需加入哈希后的 $cookie_user_id、$http_x_requested_with 或 $app_id 等业务维度,安全处理 $args 时应预清洗干扰参数,最后通过日志与响应头实测验证。

定义唯一的 fastcgi_cache_key 不是拼变量,而是明确回答:“哪些请求该共享同一份缓存”。键值重复会污染缓存(比如用户 A 看到用户 B 的数据),遗漏关键维度则导致命中率暴跌(比如移动端返回 PC 版页面)。

必须包含的核心变量

基础结构要覆盖协议、方法、主机和路径,否则连最基础的区分都做不到:

  • $scheme:区分 http 和 https,避免混用缓存
  • $request_method:GET 和 HEAD 应分开缓存,POST 一般不缓存,但若需缓存幂等接口,必须保留该变量防止覆盖
  • $host:比 $proxy_host 更可靠,能正确区分 api.example.com 和 www.example.com
  • $request_uri:含路径和原始查询字符串前缀,但注意它不自动包含参数(?a=1&b=2部分需额外处理)

按需加入业务维度变量

是否加、怎么加,取决于你的业务逻辑。加错反而破坏共享性:

  • 需要区分登录态?用 哈希后的 $cookie_user_id,例如 md5($cookie_user_id),避免明文泄露或键爆炸
  • 需要适配 API 客户端类型?优先用 $http_x_requested_with(值为 XMLHttpRequest 或空),比 User-Agent 更轻量稳定
  • 多租户或多个 PHP 应用共用缓存区?加 $app_id 或类似标识,且确保每个应用的值全局唯一;更稳妥的做法是为每个应用分配独立 keys_zone

安全处理请求参数($args)

$args 是生成动态键的关键,但直接拼接风险高:

  • 默认不包含在 key 中,所以 /report.php?s=2024/report.php?s=2025 会被当成同一个缓存项
  • 显式加入:$args 保留原始顺序和编码,适合多数场景,但要注意末尾可能带 &,建议配合 $is_args 使用(如 $is_args$clean_args
  • 过滤干扰参数:UTM 标签、随机数、时间戳等不改变内容,却制造大量无效 key。应在 http 块中用 map 预清洗,例如剔除 utm_*ts=random=

验证 key 是否真正生效

配置写完不等于跑通,必须实测确认:

  • 添加日志格式:log_format cache '$cache_key - $upstream_cache_status';,再在 access_log 中启用
  • curl -I 观察响应头:X-Cache-Status(需配 add_header X-Cache-Status $upstream_cache_status;)和 Age 字段变化
  • 检查 error.log 是否有缓存路径权限错误(如 Permission denied),Nginx 不报错但静默失效

相关文章

精彩推荐