在本机用手写的 WARC 记录实测:套接字字节原样写入并用 warcio 读回、chunked 的摘要要算在存下的字节上、requests 解码后再存会让头与正文对不上、每条记录单独 gzip 才能被 warcio 读并按偏移随机访问、revisit 记录省 29%、写到一半被截断后怎么恢复。
在本机 sqlite 3.53.4 上实测:WAL 比默认日志模式每秒提交次数高一个数量级、多线程各开连接写同一个库的 locked 错误和 busy 等待、单写线程加队列的批大小对吞吐的影响、WAL 下读写互不挡、以及长读事务会让 WAL 一直增长。
在本机 sqlite 上实测批大小:从 1 到 100 提高十几倍,1000 以后持平;行大了收益变小;只按条数攒批时慢速阶段数据会等几秒,加超时可压到约 0.2 秒;kill -9 时没提交的批会丢;一批里有一行违反约束整批回滚。
在本机服务器上抓 2000 个 URL 实测:平均值是中位数的 1.8 倍;不同分位数算法在小样本时差十几个百分点;100 个样本的 p99 可以差 10 倍;worker 各自的 p99 不能平均;超时封顶会让 p99 失真;只看状态码会把空正文算成成功。
在本机 nginx 的访问日志里看各 HTTP 库默认的 User-Agent、自报身份的 UA 与 From 头怎么出现、UA 太长 nginx 默认从 8200 字节起返回 400、中文 UA 在 requests/urllib 里报错,以及 UA 的写法怎么影响 urllib.robotparser 的匹配。
在本机独立的 redis-server 上实测任务队列的崩溃恢复:BRPOP 取出就丢、BLMOVE 加 ack 不丢但会重复、租约到期自动放回、租约比任务短会无限重复、取任务分两步会在空隙里丢任务、毒任务要有重试上限。
在本机独立的 redis-server 上实测:8 个 worker 先查再加会把 3000 个 URL 抓成一万七千多次,只用 SADD 的返回值恰好 3000 次;30 万个 URL 用 SET 存完整 URL 30.5 MiB、8 字节摘要 12.2 MiB、Bloom 位图 0.6 MiB;Bloom 同样要原子地测试并置位;DEL 一个 200 万成员的 SET 会让 PING 等 242 ms。
自己实现固定窗口、滑动窗口日志、滑动窗口计数、令牌桶四种限流器,从客户端看:固定窗口在边界附近 0.15 秒内放过两倍限额(20 对 10);整秒的 Retry-After 让客户端多等;429 后立刻重试多发 260 倍请求;AIMD 在窗口类限流下偏低。
在本机页面上量隐藏链接:17 种写法里,静态解析全部跟进,加内联样式过滤后仍有 5 个被跟进,Chrome 可见性判断只跟进 1 个(文字与背景同色),但会漏掉屏幕外的无障碍链接;遵守 robots.txt 的 Disallow 就不会碰到 /trap/;陷阱请求和所在页面的间隔只有 0.6 ms。
真实在本机起一个只收不回的假 TLS 服务器,分别用 requests 和系统 curl 连同一个端口,截获两边真实的 ClientHello 原始字节,现场算出两个完全不同的 JA3 哈希——全程没用到 User-Agent 或任何 Header;逐字段拆解 JA3 字符串,说明为什么只改 UA 骗不过基于 TLS 指纹的识别。