阻塞式代理池查询会让 Scrapy 卡住
把同步的代理池 API 调用移出 Scrapy 的事件循环路径,并让端点发现拥有自己的失败策略。
爬虫已经配置了足够多的并发请求。但每当它向代理池索取另一个地址时,仍会停顿。增加更多代理并不会改变这次停顿。
常见的中间件写法会在 requests.get(pool_url) 的调用写在 process_request() 里。在本应与 Scrapy 异步引擎协作的路径上,这是一次同步网络操作。调用等待期间,它可能拖住同一事件循环线程上的无关工作。
任务里有两个请求
一个请求从代理池服务获取端点。另一个用该端点去联系目标站点。要分别测量并分别上报。代理池 API 一旦变慢,可能在应用还没连上之前就让每个选中的代理都显得很慢。
使用已安装的 Scrapy 版本支持的异步发现集成,或者在每次请求的关键路径之外获取并刷新一组有界的本地端点。如果必须把阻塞工作卸载出去,就要给该执行器自己的上限和超时处理;无限制的队列只是把延迟挪了个地方。
不要为每个请求都自动再发起一次发现调用。短生命周期的缓存或租用的一批端点可以降低对代理池服务的依赖,前提是其有效期符合该服务真实的端点策略。
明确一次失败的查询意味着什么
代理池返回空或失败时,不应悄悄移除代理元数据并放行直连请求。要选择明确的结果:在任务预算内等待、失败,或使用已批准的缓存端点。
代理池 API 自身的路由也要保持畅通。如果它是内部服务,把它的私有主机名经由帮助选中它的那个代理发送,可能造成循环依赖。
当发现流程不再阻塞无关工作后,再去检查普通的代理事务。那是另外的修复,其耗时也应当在日志里有单独的字段。