爬虫上线后要看指标:成功率多少、延迟多少。但平均值、分位数、成功率各有几种算法,算错了会得出完全不同的结论。这篇用一个本机服务器把这几个坑逐个量出来。
总耗时 3.55 秒,平均 23.7 ms,中位数 12.8 ms,p90 26.2 ms,p95 63.0 ms,p99 266.5 ms,最大 1532 ms 平均值比中位数高 1.8 倍;低于平均值的请求占 90%
延迟分布通常是一堆很快的请求加一小撮很慢的。平均值被长尾拉高:实验里平均 23.7 ms,中位数 12.8 ms,90% 的请求低于平均值。看 p95、p99 才能看到长尾。
取前 100 个:p99 最近排名 83.4、statistics.quantiles inclusive(线性插值) 83.5、exclusive 96.9;p95 最近排名 50.3、inclusive 50.6、exclusive 55.8 取前 2000 个:p99 最近排名 266.5、statistics.quantiles inclusive(线性插值) 266.5、exclusive 270.6;p95 最近排名 63.0、inclusive 63.0、exclusive 63.1
同一批 100 个数据,p99 用最近排名法和 statistics.quantiles 的 inclusive 差不多(83 ms),exclusive 是 96.9 ms;2000 个数据时三种差在 4 ms 以内。样本少时要写明算法。
用 40 万个样本估计的"真实" p99 ≈ 305 ms 每次 100 个样本:p99 的 5%–95% 范围 64 – 629 ms,中位 172 ms 每次 1000 个样本:p99 的 5%–95% 范围 160 – 462 ms,中位 297 ms 每次 10000 个样本:p99 的 5%–95% 范围 260 – 358 ms,中位 305 ms
样本少时分位数本身就不稳定。同一个分布,100 个样本的 p99 在 64–629 ms 之间,1000 个样本是 160–462 ms,10000 个样本才收敛到 260–358 ms。统计窗口太短、请求太少时,p99 的抖动大多是噪声。
各 worker 的 p99:[322, 327, 623, 1109] ms;平均 595 ms;合在一起算 p99 366 ms;按请求数加权平均 387 ms 每个 worker 只上报直方图(桶边界 [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000] ms),合并之后估计 p99 = 500 ms(桶的上边界);换成更细的 19 个桶估计 p99 = 400 ms;精确值 366 ms
多个 worker 各自的 p99 求平均没有意义:负载小的 worker 权重被放大(实验里平均出 595 ms,真实是 366 ms)。要上报原始值或直方图再合并;直方图的桶越粗,合并后的估计误差越大(500 ms 对 366 ms)。这一节是合成数据,不是真实请求。
超时 28 个,错误类型 {'ReadTimeout': 28};超时请求记下的耗时 中位 201 ms(都被 timeout 截在 200 ms 附近)
全部 2000 个请求(含超时)p99 201 ms;只统计成功请求 1847 个 p99 78 ms;真实耗时的 p99(不设 timeout,第一节的数据)是 267 ms被 timeout 截断的请求,耗时就是 timeout 本身。含上它们,p99 被封顶在 201 ms;只算成功的,把最慢的请求都丢了,p99 只有 78 ms;真实值(不设 timeout)是 267 ms。报告里要同时给出超时的比例。
状态码分布 {200: 1895, 503: 105};只看状态码 200:1895/2000 = 94.8%;200 且正文非空:1874/2000 = 93.7%
按窗口看:前 200 个 96.5%,后 200 个 95.5%;各 200 个一窗口的 10 个窗口:[96, 95, 92, 96, 90, 95, 93, 92, 92, 96]
对失败的 126 个 URL 各重试 1 次:重试成功 57 个;最终成功率 96.5%(第一次 93.7%);一共发出 2126 个请求(多发 6.3%);重试仍失败的 69 个里,按 URL 固定会失败的有 67 个(这是我在服务器里设定的,真实站点上看不到这个标签)只看状态码 200 会把“200 但正文为空”算成功(94.8% 对 93.7%)。成功率还要说清是“第一次请求成功率”还是“重试之后每个 URL 的最终成功率”:重试一次把 93.7% 提到 96.5%,多发 6.3% 的请求,而固定失败的 URL 重试也救不回来(第 30 篇的退避、第 32 篇的分类讲过重试策略)。