需启用 log_subrequest on 并自定义 log_format,通过 $request_id 关联主子请求、$slice_range 标识字节区间、$upstream_http_content_range 验证响应,结合抓包与缓存结构交叉验证分片行为。

要监控 ngx_http_slice_module 分片回源请求的执行序列,核心不是“开启日志开关”就完事,而是需结合 Nginx 的请求生命周期、子请求(subrequest)行为、缓存状态与 HTTP 状态码,构建可追溯的观测链。它不产生独立 access 日志行,所有分片子请求默认静默执行;必须主动配置日志变量和上下文标记才能还原完整序列。
启用 slice 子请求可见性
Nginx 默认不会为 slice 触发的后台子请求记录 access log —— 它们属于 content phase 内部发起的 subrequest,不走主请求日志流程。要让每个分片回源动作“显形”,需在 location 块中启用 log_subrequest on:
- 该指令使所有由 filter 模块(包括 slice)触发的子请求,也写入 access_log
- 需配合自定义 log_format,用
$request_id或$upstream_http_content_range区分主请求与子请求 - 注意:开启后日志量显著增加,建议仅调试期启用或定向用于 /bigfiles/ 类路径
构造可追踪的日志格式
标准 $request 和 $status 对子请求意义有限(如显示为 “GET /file.zip HTTP/1.1” 且状态常为 206),需注入上下文标识:
- 使用
$request_id:主请求与所有其触发的 slice 子请求共享同一 request_id(前提是主请求已带或由 Nginx 自动生成) - 加入
$slice_range:直接暴露该子请求对应的字节区间,例如bytes=2097152-3145727 - 捕获上游响应头:
$upstream_http_content_range验证后端是否正确返回了范围信息 - 示例 log_format:
log_format slice_debug '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$request_id" "$slice_range" "$upstream_http_content_range"';
识别分片请求的典型日志模式
当客户端发起一个 Range: bytes=0-1048575 请求,且缓存未命中时,你将在日志中看到一组关联条目(按时间顺序):
- 主请求行:status=206,
$slice_range为空(因主请求未走 slice 变量生成逻辑),但$request_id存在 - 若干子请求行:status=206,
$slice_range显示如bytes=0-1048575、bytes=1048576-2097151等,$request_id与主请求一致 - 若某分片回源失败(如后端不支持 Range),对应子请求 status 可能为 416 或 502,
$upstream_http_content_range为空或异常
辅助验证与实时观测手段
除日志外,还可通过以下方式交叉确认分片行为:
-
启用 stub_status + http_slice 模块统计:虽然官方 stub_status 不直接暴露 slice 计数,但可通过
nginx -T | grep slice确认配置加载,并观察Active connections在并发 Range 请求下的突增趋势 -
抓包验证:在 proxy_pass 上游服务侧 tcpdump,过滤
tcp port 8000 and http.request.uri contains "file.zip",可直观看到 Nginx 并发发出多个带不同 Range 头的请求 -
检查缓存目录结构:若启用
proxy_cache_path ... levels=1:2,查看缓存文件名是否含slices相关哈希片段(实际由$slice_range影响 cache_key,故不同分片落不同文件)


















