统计蜘蛛抓取页面的平均响应时间,唯一可靠的算法是:平均响应时间 = 所有被判定为蜘蛛的请求的响应时间之和 ÷ 蜘蛛请求总数,其中响应时间必须取服务端记录的「请求处理总耗时」字段,而不是日志时间戳的差值。下面把字段选择、蜘蛛识别、计算命令和常见坑一次讲清。
用哪个字段代表「蜘蛛抓取的响应时间」?
结论:优先用 Nginx 的 $request_time,绝对不要用 $upstream_response_time 代替。
$request_time 是从 Nginx 读完客户端请求的第一个字节到把响应全部发给客户端之间的总耗时,单位秒、精度毫秒,最接近蜘蛛真实感受到的抓取延迟。$upstream_response_time 只统计 Nginx 转发到后端应用、拿到响应的时间,不含客户端网络传输和 Nginx 自身处理,用它算出来的均值通常比 $request_time 低 10%~30%。
最不可取的是 $time_local(精度只有秒)相减:两个相邻请求的时间差会把并发请求串在一起,误差可达 ±1 秒,对平均 100~300 毫秒的蜘蛛请求来说是致命失真。
Nginx 默认日志格式不含 $request_time,必须在 nginx.conf 里显式定义:
log_format spider '$remote_addr|$time_iso8601|$request_time|$upstream_response_time|$status|$body_bytes_sent|$http_user_agent';
access_log /var/log/nginx/access.log spider;
改完执行 nginx -t && nginx -s reload 生效,历史日志无法追溯,只能从生效时刻开始统计。
怎么从海量日志里准确筛出蜘蛛请求?
结论:先按 User-Agent 正则粗筛,再对高流量 IP 做反向 DNS 验证,能过滤掉 90% 以上的伪装爬虫。
主流蜘蛛的 UA 特征字符串是固定的:Googlebot、bingbot、Baiduspider、YandexBot、DuckDuckBot、Sogou web spider、360Spider。用一条正则即可覆盖:
Googlebot|bingbot|Baiduspider|YandexBot|DuckDuckBot|Sogou web spider|360Spider
但 UA 可以随便伪造,所以对请求量排名前 100 的蜘蛛 IP 要做「反向解析 → 正向校验」:先 dig -x <IP> 拿到域名,要求域名后缀是 googlebot.com、google.com、search.msn.com、baidu.com 等官方域,再对域名做正向解析,确认返回的 IP 与原 IP 一致。两步都通过才算真蜘蛛。
平均响应时间具体怎么算?给一条能直接跑的命令
结论:用 awk 一行即可按蜘蛛分别输出请求数和平均响应时间,比上任何 BI 工具都快。
假设日志格式是上面定义的 | 分隔:
awk -F'|' '
/Googlebot|bingbot|Baiduspider|YandexBot|DuckDuckBot/ && $5==200 {
ua = ($7 ~ /Googlebot/) ? "Googlebot" :
($7 ~ /bingbot/) ? "bingbot" :
($7 ~ /Baiduspider/) ? "Baiduspider" : "other";
s[ua] += $3; n[ua]++;
}
END { for (k in n) printf "%s 请求数=%d 平均响应时间=%.3fs\n", k, n[k], s[k]/n[k] }
' access.log
在 ClickHouse / Hive 里等价写法:
SELECT
count() AS req_cnt,
round(avg(request_time), 3) AS avg_rt,
round(quantile(0.95)(request_time), 3) AS p95_rt
FROM spider_access_log
WHERE status = 200 AND request_time > 0;
关键参数就三个:status = 200 只看成功抓取、request_time > 0 排除日志截断产生的 0 值、按 UA 分组避免不同蜘蛛被混算成一个均值。
哪些数据会污染平均值?
结论:不剔除静态资源、超时请求和预热请求,平均值会明显偏低或偏高,失去参考意义。
四个必须处理的口径问题:
- 静态资源拉低均值:CSS、JS、图片的响应时间普遍在 5~20 毫秒,而 HTML 页面在 200~800 毫秒。如果日志里混着静态资源,整体均值会被压到 50 毫秒以下,看不出真实页面性能。做法是只统计
Content-Type 为 text/html 或后缀为 .html、/ 的请求。
- 超时和中断请求:状态码 499(客户端主动断开)、504(网关超时)的
request_time 往往高达 30 秒以上,个别几条就能把均值抬高几十毫秒。建议这两类单独统计,不并入平均值。
- 均值掩盖长尾:蜘蛛抓取响应时间普遍是右偏分布,均值 300 毫秒时 P95 可能到 2 秒。只报均值会漏掉「少数页面拖慢整站抓取预算」的问题,必须同时给出 P95、P99。
- 时间窗口要一致:按天统计和按小时统计的均值可能差 20% 以上(夜间抓取密度高、服务器负载低)。对外汇报时固定用自然日 00:00–24:00,并按搜索引擎分开呈现。
实操建议:先跑通最小闭环
结论:先用 awk 拿到按蜘蛛分组的请求数和平均值,再逐步加上 P95、状态码过滤和 IP 验证,不要一开始就搭复杂的采集链路。
最小可用指标集是三列:蜘蛛名称 / 请求数 / 平均响应时间。跑通后,再加第二列 P95 响应时间 和第三列 非 200 状态码占比。这三个指标基本能回答「蜘蛛抓得顺不顺」这个问题——平均响应时间低于 500 毫秒、P95 低于 2 秒、错误率低于 1%,就属于健康状态;平均响应时间超过 1 秒,通常意味着搜索引擎会主动降低抓取频率。