zoukankan      html  css  js  c++  java
  • 【解决方案】IP代理池设计与解决方案

    一、背景

    爬虫服务请求量大,为了应对反爬措施,增加爬虫的爬取效率和代理IP使用率,需要设计一个IP代理池,满足以下需求:

    • 定时任务获取第三方代理
    • 及时剔除IP代理池中失效的IP
    • 业务隔离IP
      • 若IP未失效,但对某个业务来说,IP被封,需要针对业务,隔离此IP
    • 均衡使用IP
      • 避免IP使用频率不均问题

    通常选用的地上那方外部代理有:蚂蚁代理、阿布云、讯代理(不建议使用)。这里以讯代理为例。

    说说讯代理

    实际环境测试过,代理质量差,价格不低,客服态度不好。笔者以公司的名义提需求,价钱好商量,对方直截了当回复,没这功能,也做不了,爱买不买,呵呵。所以真心不建议使用

    1.1 调用代理API

    调用混拨代理API,返回结果

    {
    "ERRORCODE":"0",
    "RESULT":[
     {"port":"43617","ip":"222.85.5.118"},
     {"port":"43569","ip":"180.122.20.108"},
     {"port":"20443","ip":"221.230.254.73"}
    ]}
    

    二、一些知识点

    2.1 代理IP是如何产生的?

    ASDL拨号,是一种上网方式,每拨一次号,就会产生一个新的IP。而第三方的IP厂商,通常会买很多拨号VPS服务器,定时拨号来产生新的IP,提供给需要代理的客户。

    三、需求1:及时剔除IP代理池中失效的IP

    3.1 超过有效时间,自动失效

    每个IP都有固定的有效时间(拨号时间)。IP失效的原理,IP通过ASDL拨号产生,当ASDL重新拨号,则旧IP失效,新IP产生。如3分钟拨一次号,或3-10分钟拨一次号,为了保证IP的使用率,通常以最长的失效时间(如有效期3-10分钟,选10分钟作为失效时间)。

    使用Redis存储Key-Value,失效时间为最长有效时间。Key为IP+端口。Value为任意固定值。

    3.2 检测失效

    检测时间点

    • 获取到IP时,放入代理池之前
    • 在代理池中

    通常IP的真正有效时间不是固定的,比如说的有效时间是3分钟,真实有效时间可能低于3分钟。这里就需要有一个机制来单独检测IP是否有效。

    通常的做法是,IP池中的每一个IP都要定时访问一个固定的测试链接,访问失效则从队列中剔除。

    如何选择固定的链接,有下列几种要求:

    • 测试链接的网站要尽可能地稳定
    • 返回的内容要尽可能的小
    • 网站最好不要有反爬措施

    测试链接

    测试链接的一个比较好的方案是,自己提供一个CDN链接,链接指向一个只有200字符串的txt文本。

    最好提供两个CDN链接,同时请求,只要有一个能请求通,就判断为IP有效。防止一处CDN挂掉,导致所有代理IP被判定为失效。

    3.3 伪代码

    获取代理时

    
    请求API,解析获取代理列表:
       每个代理:
          if(isEffectiveIp(ip)){
    			addIpPool(ip);	
    	  }
    
    

    IP代理池中检查

    
    获取当前代理池中所有IP:
       if(!isEffectiveIp(ip)){
    		 removeIp(ip);
       }
    
    

    四、需求2:业务隔离IP

    4.1 IP隔离判定

    错误记录队列

    这里IP调用服务就需要做成一个单独的服务,其他业务服务都调用该IP服务。每次调用的时候需要上报IP,IP可用或不可用,同时附带业务名(如business-1)。

    IP服务端维持一个队列记录,记录业务与IP的错误次数,Key为业务名-IP,Value为错误次数,设置一个标准值,若连续错误N次,则将此IP放到失效队列。

    失效队列

    失效队列中,使用set存储,name为业务名称,value为失效IP

    调用IP服务
    业务每次调用IP,首先获取失效队列中的IP列表,然后请求时附带IP列表作为参数,请求不包含失效IP的任意IP。

    五、需求3:均衡使用IP

    使用zset维持,使用时间戳作为score,zset会以score从小到大排列。

    当一个IP被使用,则设置score为当前时间戳,则IP会排到队尾。

    每次获取IP时,都从队头的前N个IP中,选择一个。

  • 相关阅读:
    enum 与 enum class
    git error: unable to rewind rpc post data
    ip地址转换
    大端字节序&小端字节序(网络字节序&主机字节序)
    c++虚析构函数
    引用
    单例模式
    c++ 类静态成员、非静态成员初始化
    算法导论进度帖startedby20131029
    Linux驱动程序接口
  • 原文地址:https://www.cnblogs.com/fonxian/p/10858127.html
Copyright © 2011-2022 走看看