Nginx 不记录缓存过期时间戳或后台刷新触发等内部事件,但可通过 $upstream_cache_status、自定义响应头(如 X-Cache-Age)及日志格式间接观测缓存生命周期行为。

Nginx 本身不记录“缓存过期时间戳”或“后台刷新触发”这类内部事件的详细日志,它不会在 access_log 或 error_log 中写入某条缓存何时创建、何时失效、是否被 background update 刷新等元信息。但你可以通过组合响应头、自定义日志格式和关键变量,间接观测缓存生命周期行为。
用 $upstream_cache_status 记录缓存命中状态
这是最直接、最常用的方式。该变量反映当前请求对缓存的实际使用情况,Nginx 在每次响应中都能输出它的值:
- HIT:缓存存在且未过期,直接返回
- MISS:缓存不存在或已过期,转发给后端并写入新缓存
- EXPIRED:缓存存在但已过期(注意:不是“即将过期”,而是明确已超 proxy_cache_valid 或 inactive 时间),此时若启用 use_stale updating,则仍可返回旧内容并后台刷新
- STALE:缓存已过期,但因 use_stale 配置(如 updating、error、timeout)被允许返回
- BYPASS:因 proxy_cache_bypass 条件满足(如带特定 Cookie 或 Header),跳过缓存直接回源
- REVALIDATED:启用 proxy_cache_revalidate 后,向后端发送 If-Modified-Since/If-None-Match 并收到 304,复用旧缓存
在 log_format 中加入该字段即可追踪:
log_format cache_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$upstream_cache_status $upstream_http_x_cache_age;'
配合 $upstream_http_x_cache_age 或自定义响应头观察剩余有效期
Nginx 不原生提供“剩余 TTL”变量,但可通过以下方式暴露:
- 后端应用在响应中主动添加
X-Cache-Age: 128(表示已缓存 128 秒),Nginx 可用$upstream_http_x_cache_age捕获并记入日志 - 更推荐的做法:启用
proxy_cache_use_stale updating+add_header X-Cache-Status $upstream_cache_status+add_header X-Cache-Age $upstream_http_cache_control(若后端返回 Cache-Control),便于前端或监控系统解析 - 注意:
$upstream_http_cache_control是后端原始响应头,仅当未被 Nginx 忽略(如未设proxy_ignore_headers Cache-Control)时才有效
识别后台刷新(background update)是否生效
fastcgi_cache_background_update 或 proxy_cache_background_update 的触发无法直接打日志,但可通过“状态组合”判断:
- 首次访问 → 日志中为
MISS,后端生成响应并写入缓存 - 等待超过
proxy_cache_valid 200 5s后再次访问 → 若仍见HIT且响应极快(毫秒级),同时X-Updating: 1出现在后端访问日志中,说明后台刷新已启动 - 可在后端 PHP/Python 脚本中加日志:检查
$_SERVER['HTTP_X_UPDATING'] === '1'时记录 “background refresh triggered”
缓存文件实际过期时间不等于日志可见时间
需明确一个关键事实:Nginx 缓存条目在磁盘上的过期是被动清理的,不是定时删除。即使日志显示 EXPIRED,该文件可能仍存在于缓存目录中,直到 cache manager 进程扫描到并回收。因此:
- 日志中的
EXPIRED表示“本次请求判定为过期”,是逻辑过期,非物理删除 - 没有内置变量能告诉你“这个缓存项还有几秒到期”,因为 Nginx 不维护精确倒计时
- 若需精确控制,应依赖版本化 URL(
/api/data?v=20261001)或 PURGE 接口,而非等待自然过期











