先把两组数摆出来。同一套Java采集程序,采12个城市的二手房挂牌价,裸轮换加上直连兜底,成功率61.3%,平均每个城市跑完要重试4次以上,P95耗时2.4秒。换成带健康检查的调度层之后,成功率98.7%,P95压到900毫秒——代理源没换,代码主体没动,差的是调度。
我这边工作室常驻20多个游戏账号挂机,白天还接了个房产数据的外包:每天要拉12个城市的挂牌信息,按城市切IP。游戏那边要会话粘性,一个账号半小时内尽量别换出口;采集这边要城市精准,杭州的请求不能从南京的IP出去。两套需求塞进一个"随机取IP"的工具类,结果两头都炸。
两次翻车之后,我把"选IP"和"用IP"拆开了
第一次是游戏账号。轮换策略写的每20分钟换一次,某天代理池抖了一下,连续换出去8个不同城市的IP,第二天封了3个号。我一开始以为是IP质量差,把日志拉出来才看清:调度层压根没记录"这个账号上次用的哪个出口",粘性形同虚设。
第二次是房产采集。杭州池当时只分了300多个IP,我按1秒1个请求的节奏轮,两天后这个城市整段被封,其他城市毫发无损。到这里我才承认一件事:按城市切IP,池子的城市覆盖率比总池子大小重要得多,3000万IP里如果杭州只有200个能用的,对你就是200个。
返工的时候我没急着换服务商,先把关注点从"池子"挪到"调度"。这套Java代理IP的架构后来沉淀成三层,跑了大半年没再出大事故。
三层调度:接入、池管理、探活各管一段
第一层是接入层,按业务打标签路由:tag=game:sticky的请求走会话粘性通道,TTL锁30分钟;tag=house:city_hz走城市分区池,每请求轮换。把"选IP"的决策从业务代码里抽出来,是我认为整个改造里收益最大的一步。
第二层是池管理层,每个IP带一个健康分:初始80分,成功回写+2(上限100),失败-15,低于40分进冷却队列,冷却5分钟后重新参与调度。城市池独立成桶,桶内可用率低于70%才触发跨桶借用——这条规则是我们踩了三次才加的,早期跨桶借IP把南京的出口打到杭州业务上,采集回来一堆外地房源。
第三层是异步探活,每30秒对池内IP做一次HEAD探测,超时3秒判死。探活和业务请求走不同线程池,别让探测把业务带宽吃掉。
OkHttpClient client = new OkHttpClient.Builder()
.proxySelector(new ProxySelector() {
@Override
public List<Proxy> select(URI uri) {
ProxyNode node = pool.acquire(tagOf(uri));
return Collections.singletonList(
new Proxy(Proxy.Type.HTTP,
new InetSocketAddress(node.host, node.port)));
}
@Override
public void connectFailed(URI uri, SocketAddress sa, IOException e) {
pool.markFailed(sa, e); // 回写健康分
}
})
.connectTimeout(3, TimeUnit.SECONDS)
.build();
熔断阈值:定在多少是跑出来的,不是拍出来的
故障转移的核心参数就三个:单IP连续失败几次拉黑、拉黑多久、城市池可用率掉到多少降级。我前后试过三档,数据摊开看比较清楚。
| 调度策略 | 采集成功率 | 平均恢复时间 | 好IP误杀率 |
|---|
| 纯轮换,无健康检查 | 61.3% | — | 0% |
| 被动回写+冷却5分钟 | 92.1% | 47秒 | 6.8% |
| 主动探活30秒+被动回写 | 98.7% | 12秒 | 2.1% |
最终定的是单IP连续3次超时(3秒)进冷却,冷却5分钟;城市池可用率低于70%切备用通道,备用通道我是用隧道代理兜底的,按天计费比按量便宜,一天16块左右,专门接降级流量。说实话老板一开始嫌这笔钱是浪费,直到有次供应商整段机房被封,备用通道扛了6个小时的全量采集,他才不提了。
游戏账号那条通道不参与熔断降级,走固定粘性会话,宁可慢也不换出口——这个判断没数据支撑,纯粹是封号封怕了。
监控告警:只盯三个指标,多了全是噪音
我用Prometheus打点,告警只设三条:城市池可用率低于95%、请求P95延迟超过800毫秒、冷却队列长度超过池子20%。前两条是业务红线,第三条是提前预警——冷却队列暴涨通常意味着供应商那边在批量掉IP,比可用率报警早10到15分钟。
上线后的实际效果:房产采集12个城市全量跑完从5小时20分缩到1小时48分,游戏账号这边连续4个月零封号。中间有一次杭州池可用率掉到88%,告警响了,排查发现是供应商该城市节点在扩容,切备用通道跑了40分钟,业务侧无感知。
如果你也在用Java代理IP跑按城市切换的业务,这套三层架构可以直接抄,健康分的具体数值按你的请求频率调。我现在的主要出口是在mayihttp.com上配的,城市分区和粘性会话都支持,API提取接进池管理层大概半天工作量。这个坑踩了三次才填平,希望你能一次过。