代理套餐的并发数和流量配额总是不够用?多数问题不在代理商,而在程序的连接方式。本篇讲解连接复用、超时设置与退避重试的具体做法,用更少的配额跑完同样的任务。
为什么你的代理总是"连接数超限"
几乎所有付费代理都限制并发连接数与流量配额,超限的典型表现是 429 报错、请求排队变慢甚至账号被临时封停。很多人以为是代理不稳定,其实是自己的程序每发一个请求就新建一条连接,把宝贵的并发额度快速烧光。
连接复用:最立竿见影的优化
改用会话对象复用 TCP 连接,避免重复握手,同样的配额能支撑数倍的请求量:
import requests
session = requests.Session()
session.proxies = {
"http": "http://gw.example.com:8080",
"https": "http://gw.example.com:8080",
}
for url in url_list:
r = session.get(url, timeout=(5, 15)) # 连接超时 5 秒,读取超时 15 秒
注意长连接闲置过久会被服务端主动断开,长时间运行的采集任务应配合定期重建会话,保持连接池健康。
超时设置:宁短勿长
- 连接超时 3~5 秒: 连不上的节点不值得久等,快速失败才能快速切换。
- 读取超时 10~30 秒: 视目标页面大小而定,大文件任务可适当放宽。
- 任务级兜底: 在队列层再设一个总超时,防止个别请求挂死拖垮整个任务。
指数退避重试:别把重试变成攻击
请求一失败就立即原样重发,等于把失败请求的频率放大数倍,极易触发更严厉的风控。正确做法是指数退避加随机抖动:
import time
import random
def retry_with_backoff(task, max_retry=5):
for attempt in range(max_retry):
try:
return task()
except Exception:
wait = min(2 ** attempt, 60) + random.uniform(0, 1)
time.sleep(wait) # 约 1s、2s、4s、8s,叠加随机抖动
raise RuntimeError("重试次数用尽")
配额优化的整体思路
- 队列限流: 用信号量或消息队列把全局并发压在套餐限额的八成以内,留出缓冲空间。
- 分级请求: 列表页等高频低价值请求走廉价通道,详情页等关键请求走高质量代理。
- 增量采集: 只抓有变化的数据,配合缓存与去重砍掉无效请求,往往比任何调参都省配额。
- 用量监控: 实时统计每类任务的流量消耗,把配额花在产出最高的环节。
先做连接复用,再收紧超时,最后加上限流与退避,这套组合拳打完,同样的套餐往往能多跑一半的任务量。
Article ID: 69
(本文仅供技术交流,请遵守法律法规)