做爬虫的估计都遇到过这种时候:昨天还跑得好好的任务,今天突然慢到怀疑人生。第一反应基本都是"代理不行了",然后开始骂服务商、准备换套餐、翻新的 IP 池。
我最近在做一个电商价格监控项目,请求量从日均 20 万涨到 80 万之后开始出现明显的耗时抖动。当时的第一反应也是换代理,但把请求耗时按 DNS、TCP、TLS、首字节、传输拆开测了一遍之后发现:一半以上的瓶颈其实落在采集系统内部和目标站的限速策略里,跟代理链路关系不大。
这篇把我完整的排查思路整理了一下,包括当时用极安代理做基线对照的具体数据,希望能帮后面遇到类似问题的人少走弯路。
一句话总结:先分层测量再决定动手方向,比直接换服务商省时间也省钱。
先看症状:慢的表现有六种
"慢"是症状不是诊断。不同表现指向不同的锅:
| 症状 | 具体表现 | 大概率在哪 |
|---|---|---|
| 单请求 TTFB > 3s | time_starttransfer偏高 | 目标站服务端处理慢或触发限速 |
| 连接建立 > 500ms | time_connect高,TLS 也慢 | 代理链路或运营商出口 |
| 首次 DNS > 200ms、后续正常 | time_namelookup首次慢,后续为 0 | 采集端没 DNS 缓存 |
| 并发拉到 50 就卡住 | CPU/带宽都没打满,QPS 不涨 | 连接池、线程模型、GIL |
| 成功率下降伴随耗时上升 | 4xx/5xx 变多 | 触发风控或 IP 被识别 |
| 单 IP 用几分钟就慢 | 换 IP 立刻恢复 | 目标站按 IP 限速 |
对号入座只是起点,真正判断责任还得靠下面的分层测量,别靠感觉。
排查前,手上得有三样东西
少一样都很难查得清楚。
历史基线。正常的时候 P50、P95 是多少,DNS/TCP/TLS 各段是多少。没有基线,"变慢"就只是主观感受。我一般让每个采集任务上线时留一份 100–1000 次请求的耗时分布日志,后面对比全靠它。
分层测量脚本。curl 的-w参数最轻量,一条命令把请求拆成五段:
curl -o /dev/null -s -w "\ time_namelookup: %{time_namelookup}\n\ time_connect: %{time_connect}\n\ time_appconnect: %{time_appconnect}\n\ time_starttransfer: %{time_starttransfer}\n\ time_total: %{time_total}\n" \ -x http://代理地址:端口 https://目标站.com读法很直接:
DNS 解析:
time_namelookupTCP 握手:
time_connect - time_namelookupTLS 握手:
time_appconnect - time_connect服务端处理:
time_starttransfer - time_appconnect内容传输:
time_total - time_starttransfer
哪段异常查哪层。
两组对照。同一目标站,走代理 vs 直连;同一代理,打目标站 vs 打谷歌/百度这类基线站。四组数据摆出来,代理、目标站、本地网络的问题基本能自证清白。
原因清单:按概率排序,别从最贵的假设开始
我一般按下面这个顺序排:
| 优先级 | 原因 | 触发条件 |
|---|---|---|
| 高 | 采集系统内部瓶颈 | 高并发、长时任务、没 DNS 缓存 |
| 高 | 目标站限速/风控降速 | 数据量突增、单 IP 密度高、请求太机械 |
| 中 | 代理链路本身变慢 | 换了服务商、IP 池老化、带宽被打满 |
| 中 | 网络出口/运营商链路波动 | 时段性、跨运营商 |
| 低 | 目标站服务端故障 | 大促、活动、平台故障 |
有点反直觉:大部分人第一反应是查代理,但代理其实排第三。跳过前两个直接换服务商,是最常见的判断错位。
代理链路问题:分三层定位
代理的排查分三层:DNS、TCP+TLS、带宽。
怎么判断锅在代理?
拿前面那两组对照数据比:走代理时time_connect比直连高 200ms 以上、time_appconnect也跟着升高,多半是代理入口或代理到目标站的链路问题;仅time_namelookup高、其他都正常,是 DNS 层有问题;time_total - time_starttransfer段异常长、下载速率明显低于历史基线,是带宽被打满了。
怎么处理:
DNS 层:先看采集端走的是不是系统 DNS、有没有命中本地缓存。隧道代理场景下 DNS 解析在服务端,还得看服务商入口 DNS 的响应时长。
TCP+TLS 层:看代理入口所在机房到目标站的物理路径。跨地域访问建议就近选节点,别让北京的机器绕到广州的代理再打上海的站。
带宽层:看代理产品单业务的带宽参数。1M 带宽下并发 50 个 500KB 页面必然堵,5M 起是持续高频采集比较常见的档位。
验证修好:修完跑 100 次,P95 回到历史基线的 1.2 倍以内算修好;仍偏高就说明瓶颈不完全在这层,回去看对照组。
评估代理服务商,我看的三个参数
评估代理服务商能不能扛住当前负载,看的不是 IP 池总规模——那玩意儿基本是营销数字——而是三个能验证的参数:单业务带宽底座、异常 IP 自动切换能力、可用率。这几个直接决定你在高并发下能不能贴合历史基线。
我这次项目最后选的是极安代理,主要看中的就是这三个参数对得上高并发采集的场景:
| 评估维度 | 一般代理 | 极安代理 | 高并发采集实测影响 |
|---|---|---|---|
| 单业务带宽 | 1M–3M 常见 | 默认 5M 底座 | 5M 下并发 100 才不堵,1M 到 50 就爆 |
| 可用率 | 说 99% 的多 | 官方披露 99.9% | 每天多 0.9% 的失败率,日均 80 万请求 = 7200 次白跑 |
| 异常 IP 处理 | 需要程序端重试 | 服务端自动切换 | 程序端逻辑少一层,出错概率降一半 |
评估时看这几列,别看 IP 池总数。如果你有其他候选的话,直接拿它们的官方参数填进去横着比就行。
目标站限速:怎么和代理故障区分
目标站降速的表现跟代理故障几乎一样:请求慢、成功率降、耗时飙。区分它们的关键就一个:换 IP 后立刻恢复吗?
判断方法:
拿一个全新的 IP 立刻打同一路径,如果time_starttransfer立刻回到基线,就是目标站按 IP 限速;换 IP 依然慢,问题不在这层。
需要提醒的是,现在的风控系统看的维度早就不只是 IP 频率,还包括请求头、Session 深度、访问路径、行为模式。单 IP 密度过大只是最容易被抓到的一种。
怎么处理:
短周期任务用短效代理,IP 存活 1–15 分钟自动失效,不给目标站建 IP 画像的窗口;
持续任务用隧道代理,换 IP 放到服务端,程序无感切换;
请求节奏别用固定 sleep,改成基于响应时间的自适应——响应慢就退避,快就恢复;
Session 得模拟真人:先访问首页建立信任,走列表页再进详情页,别一上来就直捣详情页 URL——那在风控眼里跟裸奔没什么区别。
验证修好:连续 500 次,成功率 98% 以上、P95 回到基线 1.5 倍以内算修好。
摸目标站的降速阈值:先用免费额度跑一份基线
做持续采集的团队,一般都是先花小钱跑一周,摸清目标站的降速阈值和风控画像,再决定要不要上更贵的资源。
我这次的做法是先用极安代理新注册账号送的 8 小时免费测试额度跑基线——这个时长够连续采 3–4 万次请求,能把目标站的降速拐点画出来。具体拐点数据(脱敏后)大概是:
单 IP 请求密度超过 0.8 QPS,第 3 分钟开始出现耗时翻倍
单 IP 累计请求超过 400 次,触发一次 302 到风控页
请求间隔完全固定(比如 sleep 1 秒),累计到 200 次就被识别
有了这份基线,才好决定用多长的 IP 存活周期、并发拉到多少合适。摸阈值这个阶段的目标不是采到多少数据,是拿到一份可信的耗时分布——把测量成本和采购成本分开算,比一上来就买年套餐合理得多。
采集系统内部瓶颈:最容易被忽略
代理和目标站都排掉了,剩下就是自己的系统。这是概率最高的一档,但心理上最难承认。
怎么判断?三个信号一起出现基本就是它:
CPU 和带宽都没打满
QPS 不再随并发数增长
time_namelookup首次高、后续也高
怎么处理:
DNS 缓存。默认 socket 每次请求都会重新解析,几十毫秒的开销在高并发下被无限放大。给采集程序打个 DNS 缓存补丁,字典存已解析域名的结果,同域名后续请求直接读缓存,收益立竿见影。Scrapy 直接在 settings 里开DNSCACHE_ENABLED就行。
连接池复用。用requests.Session复用连接,减少建连开销。连接池大小和 Keep-Alive 超时要显式配置,默认值对高并发场景来说通常小得离谱。
异步替换同步。同步requests+ 线程池的组合,QPS 上限一般在 100–200,很难再往上推。换成 aiohttp 之类的异步库,等响应的时候可以继续发别的请求,QPS 能有质变。
GIL 和多进程。Python GIL 卡 CPU 密集任务的并行度。如果解析很吃 CPU,把解析拆到独立进程、采集主循环只做 IO——这是最常见的解耦方式。
验证修好:同代理、同目标站的条件下,QPS 应该有 2–5 倍提升,CPU 或带宽至少有一项接近打满。两项都没打满,瓶颈还在别处。
什么时候该停下来
不是所有慢都值得自己查到底。三种情况建议直接停手,避免越查越乱:
跨运营商链路波动。电信、联通、移动之间骨干链路抖动,采集端修不了,等或者换出口。
目标站整体故障。大促、活动、平台本身故障时所有人都慢,任何优化都是无效动作。上第三方状态页确认一下就行。
生产高峰期改配置。风控看行为模式,高峰期突然换代理、突然改节奏,触发风控的概率反而更高。稳妥做法是灰度切一小部分流量验证,通过再放量——所以工程侧最好留一个能低成本切代理入口的开关。极安代理的隧道代理支持 API 切换、按时计费按需扩容,我做灰度回滚基本几分钟就能完成一次入口切换,这个能力在高峰期是真的救命。
FAQ
Q:换了代理服务商还是慢,问题一定在采集系统吗?
不一定。先做四组对照(走代理/直连、目标站/基线站)。直连基线站也慢,问题在本地或采集端;只有走代理打目标站慢,还得看 curl 分层数据落在哪段。
Q:DNS 缓存开了会不会命中过期的解析结果?
会,所以 TTL 要设合理,一般 300–600 秒稳妥。目标站的域名解析极少变化,过期风险远低于每次重新解析的性能损失。生产环境留一个手动清缓存的开关就够了。
Q:短效代理和隧道代理,什么场景该用哪个?
短效适合频繁换 IP、批量提取、临时任务、短周期采集;隧道适合持续请求、程序端无感换 IP。判断依据不是"哪个更好",而是任务的请求节奏和持续时长。我在极安代理上买的是短效 + 隧道组合——批量类的任务走短效(1000 IP 3.6 元/天起,1–15 分钟五档存活可选),常驻类的采集走隧道,两种入口在同一个后台切,逻辑上清爽很多。
Q:预算不多,怎么低成本先试跑一份基线?
看服务商有没有免费测试额度。极安代理给新注册账号 8 小时免费测试,这个时长能采 3–4 万次请求,够画出目标站的降速拐点。摸阈值阶段的目标不是采数据,是拿一份可信的耗时分布,别一上来就买年套餐。
Q:怎么判断是按 IP 限速还是按账号/Cookie 限速?
保持请求头、Cookie、UA 完全一致,只换 IP 打同一路径。耗时立刻回到基线是按 IP;换 IP 依然慢但清 Cookie 后恢复是按会话。
Q:curl 分层测量只能测单次,怎么持续监控?
写进定时任务,每分钟采样一次,各段耗时进 Prometheus 之类的时序库。告警口径用"P95 相比昨天/上周是否上升",比"绝对值超过多少毫秒"实用得多。
最后
分层测量的意义不是让你查得多细,而是让你在花钱之前知道钱该花在哪。这个思路对代理、对 CDN、对任何网络中间件都成立——先把请求拆开测、让数据说话,比拍脑袋换服务商靠谱得多。
我这次项目最后的账是:换代理花的钱不到总预算的 20%,剩下 80% 花在了 DNS 缓存补丁、连接池调优、请求节奏改自适应这些采集系统内部的改动上。这个比例可能反直觉,但它挺真实的。
如果你也有过"以为是代理,最后发现是自己代码"的经历,欢迎评论区聊聊,互相避坑。