上周财务把过去半年的代理采购单拉了个汇总,数字是11.7万元。我顺手把它和我们团队的事故记录做了对照,发现其中约71%的钱,是在三次翻车期间烧掉的——不是正常业务消耗,是故障期间的无效重试、紧急换供应商和加班。作为一支负责票务抢购系统数据链路的技术团队,这个比例让我有点坐不住。
票务抢购这个场景对代理的要求很拧巴:开票瞬间并发能从日常两百冲到三千以上,IP被平台风控盯上就直接掉验证码,而下单链路又要求同一出口IP维持几分钟不换。三个约束互相打架,我前后换了三种接入形态才摸清门道。
坑一:池子看着够大,先跪的是提取接口
第一次选型我们盯着宣传页上的池子规模,挑了一家号称千万级IP的按量短效服务。日常跑得很稳,可用率一直在99%以上,我一度觉得这事成了。
开票日打脸。前端并发从200拉到3000,本地IP池五分钟见底,程序开始疯狂调提取API补货。对方接口限速20次/秒,我们瞬间打满,触发了长达90秒的封禁。那90秒里可用率从99%掉到61%,业务方电话直接打到我手机上。
问题不在池子大小,在于提取接口的QPS上限才是真实吞吐瓶颈。后来我们改成预热模式:按峰值QPS的1.2倍提前备池,并且用固定频率拉取而不是按需拉取。
- 开票前5分钟启动预热,目标池容量 = 预估峰值QPS × 1.2
- 提取频率控制在对方限速的60%以内,留出突发余量
- 池内IP打上获取时间戳,超过生命周期70%就提前淘汰
核心逻辑大概是这样:
def warm_up(target_qps): need = int(target_qps * 1.2) while POOL.qsize() < need: r = requests.get(API, timeout=3).json() for ip in r["data"]: POOL.put(ip) time.sleep(1) # 卡住频率,别把提取API打限流
说实话这个坑我们踩了两次,第一次以为是对方服务不稳定,第二次才发现是自己把API打爆的。
坑二、坑三:脏IP掉验证码,会话漂移掉单
补上预热逻辑后,可用率稳住了,但订单成功率还是上不去。排查了两周,发现是两个独立问题叠在一起。
脏IP是第一个。短效池里有一部分IP已经被目标平台标记过,请求直接进验证码环节。我们写了个小脚本,拿到IP先打一次检测请求,统计了三家服务商各1000个样本的脏IP率,差距比我预想的大得多:
| A(低价按量池) | 7.3% | 11.4% | 68ms |
| B(中型池) | 2.1% | 4.2% | 41ms |
| C(隧道代理) | 0.8% | 1.6% | 9ms |
会话漂移是第二个,也更隐蔽。我们的下单链路是登录→选座→支付,全程要求同一出口IP,窗口大概3到5分钟。短效IP一分钟一换,到支付环节IP已经变了三轮,风控直接判异常。这个问题在监控上表现为"支付失败率上升",跟代理看起来毫无关系,我们查了三天日志才定位到。
解决办法是换成支持会话保持的隧道代理,在请求头里带上Session-ID,绑定时长设成300秒,且在下单成功前不主动释放。切换后支付环节的异常率从6.8%降到0.9%。
现在我们怎么选:三条硬指标和一张清单
走过这三遭,我现在的选型逻辑跟两年前完全反过来了——不看池子多大,先问三个数:
- 提取API的QPS上限:这个数直接决定你高峰期的补货能力,比池子总量重要十倍
- 脏IP率实测值:要求对方给试用额度,自己跑1000个样本统计,别信标称的可用率
- 会话保持的最短绑定窗口:低于180秒的,别用在有支付、提交类动作的链路上
架构上我们现在是两层:隧道代理扛主力(延迟稳定在10ms以内,可用率实测99.9%),本地自建池做二级调度和溢出承接,按量短效池只在极端峰值时启用。这个组合在日均200万请求的量级下够用;如果你们是千万级,调度层还得再加一层地域分流,我目前没跑到那个量级,不敢乱给建议。
另外提醒一句,别把白名单认证当成省事的选择。我们团队多环境并行,账密认证配错了两次导致整组IP失效,后来统一改成API提取+本地池,反而好排查。这类配置细节在文档里往往一笔带过,但真出事时全是它。
现在主力的隧道通道我们用的是蚂蚁代理,16元/天起的档位,接入前跑过一周脏IP抽检,0.8%左右,跟他们的3000万IP池和99.9%可用率标称值基本对得上,具体参数可以去 mayihttp.com 自己核。选型这事没有标准答案,但把上面三个数问清楚,至少能少烧几万块冤枉钱。