IP 池的 5 个常见坑,第 3 个我栽了大半天才爬出来
搭 IP 池这件事,看起来挺简单------把 IP 存起来,用的时候拿一个,不行了换下一个。但实际跑起来你会发现,各种小坑层出不穷。
我把见过的几个常见坑整理一下,按"最容易栽"的程度排个序。
坑 1:IP 没检测就上线
新手最容易犯的错。代码写完,直接把一批 IP 灌进去就开始跑。结果跑起来才发现,池子里一半 IP 都是失效的,请求失败率 50% 以上。
正确做法 :上线前必须经过可用性检测。最简单的检测是拿每个 IP 发一次请求,能连通就放进去,不通的剔除。
python
def validate(ip):
try:
r = requests.get("http://example.com",
proxies={"http": f"http://{ip}"},
timeout=5)
return r.status_code == 200
except:
return False
# 批量检测
new_ips = [...]
for ip in new_ips:
if validate(ip):
r.sadd("ip_pool:available", ip)
这个坑听起来很基础,但每次有人新搭 IP 池都会有人栽。
坑 2:失败 IP 不剔除
检测上线后,池子是好用了。但跑着跑着会发现,可用率慢慢下降------因为有些 IP 在用着用着的时候失效了(对方维护、网络抖动、被目标网站拉黑),但代码里没人把这些失效的 IP 移走。
正确做法 :每次请求失败后调用 report_failure(ip),失败次数超过阈值就临时剔除。
python
def report_failure(ip):
count = r.incr(f"ip_pool:fail_count:{ip}")
if count >= 3:
r.srem("ip_pool:available", ip)
r.sadd("ip_pool:temp_blacklist", ip)
这个坑的特点是初期不显、后期爆发。刚上线那几天一切正常,跑了一周以后池子里一半都是死 IP,性能断崖式下跌。
坑 3:冷却时间没设
这是我栽得最久的一个坑。
当时我写的代码是这样的:
python
def acquire_ip():
return r.srandmember("ip_pool:available")
每次从池里随机拿一个。没有冷却时间。
跑起来之后,业务那边反馈说"同一批请求里好几个用了相同的 IP"。我以为是池子里的 IP 不够多,加了一波 IP,问题没解决。又以为是目标网站的反爬规则变了,调整了请求头,没用。
最后抓包一看才发现:因为没有冷却时间,两个并发请求极有可能拿到同一个 IP。
解决方法是在取 IP 时加一个 5 秒冷却:
python
def acquire_ip():
while True:
ip = r.srandmember("ip_pool:available")
if not ip:
return None
if r.set(f"ip_pool:cooldown:{ip}", "1", ex=5, nx=True):
return ip
加完之后并发请求不再撞 IP 了。这个坑的隐蔽性在于,你以为是池子或反爬的问题,其实是并发调度的细节。
坑 4:单点依赖
很多小型项目会把 Redis 部署在和业务同一台机器上。一旦这台机器重启或者 Redis 挂了,整个 IP 池就完蛋了。
更隐蔽的是:很多人以为 Redis 挂了池子就只是不能用,等 Redis 恢复就好了。但实际上 Redis 恢复后,内存里的所有数据都没了------之前加的 IP 全部消失,得重新加。
正确做法:
- Redis 做持久化(AOF + RDB 双开)。
- 关键数据(IP 池、剔除记录)做定期备份。
- 如果规模再大一点,Redis 用主从或者哨兵。
这个坑不是"代码写错了",是"运维层面的健壮性"。但运维问题往往比代码问题更要命。
坑 5:监控缺失
最后一个坑,也是最容易被忽视的坑:IP 池跑起来了,但没有监控。
出了问题不知道------池子空了不知道,可用率掉了不知道,某个 IP 段集中失效也不知道。
正确做法:加几个关键指标的监控:
python
def stats():
return {
"available_count": r.scard("ip_pool:available"),
"in_use_count": r.scard("ip_pool:in_use"),
"blacklist_count": r.scard("ip_pool:blacklist"),
"fail_rate_last_hour": ...,
}
把这些指标接到监控告警里。池子低于某个阈值、可用率突然下降,都应该报警。
我自己的习惯是:任何长期跑的服务,至少要有"池大小"和"成功率"这两个指标的实时面板。出问题能 5 分钟内发现,比什么都重要。
写在最后
5 个坑串一下:
- 没检测就上线 → 上线前必须验证可用性。
- 失败不剔除 → 必须有失败统计和剔除机制。
- 没冷却时间 → 并发场景下必须有冷却,避免撞 IP。
- 单点依赖 → Redis 要做持久化和主从。
- 监控缺失 → 关键指标要有实时面板。
这 5 个坑,每一个我都在不同项目里栽过。把这份清单记下来,下次新搭 IP 池时拿出来对一遍,能少走不少弯路。
搭基础设施这事,难的不是技术,是"想到所有可能出问题的地方"。每个坑的背后都是一个真实的事故现场。能把这些坑提前避开,你的 IP 池就能稳定跑很久。