先看现象。慢查询日志里一条列表页 SQL 稳定跑 2.3 秒,蜘蛛抓取超时率从 2% 涨到 30%,用户端因为缓存感觉不明显,抓取统计里的平均响应时间同步上升。

这类报错背后常见的原因有几处,逐个排除就行。列表页按多字段排序,缺少联合索引。少数情况下是分页用了大 offset,扫描行数随页码线性增长。

不容易想到的是,连接池偏小,慢查询把连接占满。

还有一种情况,缓存命中率下降后请求全部落到数据库。

从慢查询日志里找出耗时最高的语句

pt-query-digest /var/log/mysql/slow.log | head -40

给排序字段补联合索引并看执行计划

EXPLAIN SELECT id,title FROM posts ORDER BY created_at DESC LIMIT 20;

接着把大 offset 改成游标分页

SELECT id,title FROM posts WHERE id < 10240 ORDER BY id DESC LIMIT 20;

末了确认接口响应时间回到阈值内

curl -s -o /dev/null -w '%{time_total}\n' 'https://www.example.com/api/list?page=1'

改完先别撤,确认这几项。列表接口响应时间降到 200 毫秒以内,蜘蛛超时率回落到 3% 以下,抓取量一周内恢复。

蜘蛛对响应时间的容忍度比用户低,缓存能救用户体验,但救不了抓取预算。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189