又到了每月做项目复盘的时候,会议室里同时摆着三份数据。
代理服务后台显示节点运行正常;采集程序里,大部分请求也拿到了 HTTP 响应;可到了数据同事那边,真正进入语料库的有效页面却少了一截。
项目经理问:“是不是这批 IP 不行?”
开发觉得不是。他那边多数请求返回的都是 200。
数据同事也不同意。状态码虽然正常,页面里该有的正文却没有,有些返回的是验证页,有些只剩一层页面框架,还有一批是在解析阶段丢掉的。
三个人说的都有道理。
也都没回答问题。
我把那天的日志重新按阶段拆了一遍,才发现大家嘴里的“成功率”根本不是同一个东西:代理服务商说的是节点可连接,开发说的是请求有响应,数据同事说的是内容能入库。前两个数字看着都不差,最后一个才是甲方真正要交付的结果。
这就有意思了。
同一批请求,只因为统计停在不同位置,就能得到三种完全不同的成功率。再把目标站点、会话状态、并发、重试和解析程序混进来,数字当然越看越像玄学。
说白了,代理 IP 成功率不是一个单独由 IP 决定的指标。它是代理资源、网络过程、目标端判断、请求行为和本地程序共同跑出来的结果。
如果只盯着“换了多少条 IP”,却不问失败发生在哪一层,换再多供应商也可能是在重复同一种排查错误。
先把“成功”说清楚
问一家代理服务商“你们成功率多少”,跟问一个程序员“你代码快不快”差不多。
缺少测试对象、并发、时间窗口和成功标准,这个问题没有答案。
往下拆一层看,一次数据采集至少经过四道判断。
| 层级 | 真正要判断的事 | 常见失败 |
|---|---|---|
| 代理连接 | 客户端能否连上代理节点 | 连接超时、鉴权失败、节点不可达 |
| 目标响应 | 请求是否到达目标,并收到响应 | TLS 握手失败、目标超时、连接中断 |
| 业务有效 | 返回内容是否为所需页面或数据 | 403、429、验证页、登录页、空壳页面 |
| 数据入库 | 内容能否被解析并进入后续任务 | 字段缺失、页面改版、解析异常、去重误杀 |
真正对业务有意义的,通常是最后一层。
所以我更习惯把它理解成:
最终数据成功率=代理连接率 × 目标响应率 × 内容有效率 × 解析入库率
这不是用来做财务结算的严格公式,而是一个排障框架。任何一层掉下去,最后拿到的数据都会变少。
问题恰恰出在这儿。
有些测试把“代理服务器返回了响应”算成功;有些测试要求 HTTP 状态码为 200;还有些项目只有在目标字段完整入库后才算成功。三种口径算出来的数字都叫成功率,实际完全不是一回事。
IP 能连上,不代表业务就能跑通
代理 IP 行业里最容易混淆的两个概念,是“IP 可用率”和“业务成功率”。
IP 可用率回答的是:这条代理能不能建立连接。
业务成功率回答的是:使用这条代理,能不能在指定目标、指定时段、指定请求方式下,拿到可用结果。
中间隔着目标站点的访问规则、请求频率、会话状态、页面结构和业务代码。只看代理是否连通,最多证明基础网络没断,证明不了任务一定成功。
我见过最典型的情况,是检测 IP 的页面全部正常,真实业务一跑就掉。原因也不复杂——检测网站不关心你的访问节奏,目标网站关心;检测网站只接收一个简单请求,真实任务可能要连续翻页、保持会话、加载接口,还要解析页面。
拿检测网站的结果替代真实业务测试,相当于在停车场试了一脚油门,就宣布这辆车能跑川藏线。
不行。
资源类型选错,池子再大也没用
代理不是简单地分成“好 IP”和“坏 IP”。
数据中心代理、住宅代理、移动网络代理、静态代理,网络属性不同,适合的任务也不同。公开页面可能用数据中心代理就能稳定完成,某些对网络环境更敏感的目标,则会对地址类型、所属网络和历史使用状态作出不同处理。
这地方很多人踩坑——成功率掉了以后,第一反应是扩大 IP 池。
池子大只能说明可调度资源多,不代表这些资源适合当前目标。资源类型不匹配时,多拿十倍 IP,也可能只是把同一种错误重复十遍。
IP 的历史状态也要算进去。同一地区、同一运营商的两条 IP,表现可能完全不同。某条地址过去承载过什么请求、使用频率多高、所在网段有没有形成异常特征,都会影响后续表现。
用户拿到的是一个地址,看不到它过去经历过什么。
所以,“我已经换了新 IP,为什么还不行”这句话,本身就有问题。新拿到,不等于历史状态是新的。
会话没管好,换 IP 反而会降低成功率
不少采集程序把“失败就换 IP”写成默认规则,看上去很合理,实际经常误伤正常会话。
假设一个任务需要先访问入口页,取得 Cookie,再调用列表接口,最后进入详情页。前三步本来属于同一个会话,程序却在第二步超时后立即切换出口,目标端看到的就是:Cookie 没变,请求环境没变,IP 突然去了另一个地区。
严格讲,这不一定会直接导致封禁,更常见的是会话被重新验证、请求被重定向,或者返回一个内容不完整的页面。只不过业务程序没识别出来,最后又记成了“代理失败”。
另一种情况正好相反。
一个本该高频轮换的公开数据任务,被长期固定在少数出口上。前几分钟表现正常,频率积累到某个程度后,成功率开始持续下降。程序继续重试,出口压力更集中,然后掉得更快。
代理轮换不是越频繁越好,也不是越稳定越好。要看一次业务会话究竟从哪里开始、在哪里结束。
无状态请求可以按次轮换;需要连续操作的任务,要让 Cookie、客户端状态和 IP 的生命周期对得上。先定会话边界,再决定换 IP 的时机,顺序不能反。
并发一上来,原来隐藏的问题都出来了
开发环境里跑十几个请求正常,不代表生产环境持续并发也正常。
并发提高以后,变化的不只是请求数量。单位时间内的访问密度上升,同一出口承担的压力变大,本地连接池开始排队,文件描述符和带宽被占满,超时请求又会挤压后续任务。
还有重试。
不少程序遇到超时后,会在极短时间内原样重发,而且连续重试时仍然使用同一出口。目标已经表现出限频或异常,程序却在帮它快速累积更多异常请求。
我做语料这几年,对“自动重试”四个字越来越谨慎。重试不是修复机制,它只是重新执行一次。失败原因没有消失,再执行五次,也只是得到五份失败日志。
连接超时、鉴权失败、403、429、目标端 5xx 和解析异常,处理方式不该一样。至少要先判断失败发生在哪一层,再决定等待、换节点、降低频率,还是直接停止任务。
把所有错误都交给“换 IP+立即重试”,代码倒是省事,线上会很热闹。
有时候,代理只是在替本地程序背锅
这类问题我踩过,而且不止一次。
程序日志里写着“代理请求超时”,排查到最后,代理连接只用了几十毫秒,真正耗时的是本地任务在队列里等了几秒。等它拿到连接准备发请求时,总超时预算已经快用完了。
还有些项目只记录一个总耗时,不区分代理建连、TLS 握手、目标首字节、内容下载和页面解析。任何一步慢了,最后都显示同一个错误。
这种日志几乎没有排障价值。
超时至少要按阶段记录。代理建连慢,查节点和网络路径;建连正常、首字节慢,查目标响应与请求策略;内容已经返回、解析阶段报错,就别再给供应商提“IP 不稳定”的工单了。
解析规则失效也很常见。目标页面改了一个字段,程序没有取到内容,于是把空数据记成请求失败。运维去换代理,开发去调重试,忙一圈,页面上的字段名还在那里安静地变着。
我做了十年数据采集,前年还在踩这种坑。别笑。
平均成功率最会骗人
假设一个任务的总体业务成功率看起来还可以,按地区拆开后,却可能是一部分地区长期稳定,另一部分地区持续失败。
按时间拆,也可能发现白天正常,业务高峰开始下降。
按目标页面拆,还可能是列表页正常、详情页异常;公开页面正常、需要会话的页面异常。
这时继续讨论一个总体平均数,没有多少意义。
成功率至少要能按目标、地区、运营商、代理类型、时间窗口、并发档位和失败原因拆开。你不一定每天都看这么多维度,只不过日志里要留得下来,不然问题发生以后只能猜。
有时总体数字下降,并不是所有请求都变差,而是某个占比很高的目标单独出了问题。平均值把问题抹平以后,看上去就像整批代理突然一起坏了。
代理没那么团结。
我现在怎么测试一批代理
换供应商或者更换资源类型时,我们工作室一般不会直接把生产流量全部切过去。流程不复杂,关键是控制变量。
- 先定义成功。 是完成代理连接,收到
200,拿到正常业务页面,还是字段完整入库。口径先写死,中途不改。 - 用真实目标测试。 不只访问 IP 检测页,也不用厂商提供的演示目标。拿自己实际业务中有权限访问的公开或授权页面跑。
- 固定条件跑够时间。 地区、并发、请求方式、超时和会话策略保持一致,至少覆盖 48 小时的业务波动;准备正式上量前,我更倾向于小流量跑一周。
- 同时看成功率、IP 重复率和 IP 寿命。 成功率只能说明结果,重复率和寿命能帮助判断池子的实际调度情况。
每轮测试只改一个变量。
这句话看起来像中学实验课要求,线上排障时却最容易被忘掉。有人同时换了代理类型、并发、超时和重试间隔,成功率上升以后,谁也说不清究竟是哪一项起了作用。