1 Star 0 Fork 0

goodhans / proxyip_old1

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
README.md 5.80 KB
一键复制 编辑 原始数据 按行查看 历史
virjar 提交于 2016-12-18 20:12 . update

#client运行原理 这里讲述IP池的设计相关,如果您仅仅是为了使用dunproxy-client,则不必关心本文内容

client就是一个代理IP池的实现,IP池的设计基于两个点 1)代理IP都是不稳定的,不可靠的,需要一个机制来切换IP,尽可能使用高质量IP。2)IP和环境关系很大,同一个IP在不同的机器下访问不同的目标网站,其可用性表现都是不一样的

下面讲述client如何通过某种策略规避上面两个问题。

client结构如下图: img

解决IP环境依赖问题的方式,那就是为每个目标维护一个资源池,所以就客户端结构来说,每个域名下的IP资源都是独立的。然后则是预校验机制,所以IP在加入到IPPool的时候,都需要进行可用性探测。这样保证IP在加入的时候,都是可用的

另一个问题,则是保证高质量IP被绑定到的概率更高。为了实现这个目的,我们设计了两个模型。

IP容器模型:smartProxyQueue IP池的核心模型和算法,体现和普通IP池的差异的核心竞争力😄

smartProxyQueue是一个链表,用来实现IP轮训切换的队列,但是和一般的队列不同,他不是完全符合先进先出的规则的,而是一个高质量IP轮训,低质量候补的队列。这样,保证IP可以切换使用,且每次切换的IP都是较高质量的。 smartProxyQueue的结构如下: img 队列分为轮询区域,候补区。他是在LinkedList上面的一个逻辑区域划分,使用一个ratio参数控制。轮询区域的资源没有分值优先级概念,每次使用IP从轮询区头部获取一个IP,并将其插入到轮询区的尾部。如果这些IP始终都没有失败,那么很完美,容器只会使用轮询区的IP。

获取一个IP的时候,流程如下 img 轮询区域的资源没有分值优先级概念,每次使用IP从轮询区头部获取一个IP,并将其插入到轮询区的尾部。

如果绑定的IP没有失败,则不进行队列位置调整

如果IP存在失败,那么进去失败候补流程,如下图: img 不论此时IP在轮询区那个位置,都把他取出来,然后计算当前分值,根据分值插入到候补区的某个位置,候补区这是一个优先级区域了,分值高的资源将会存在候补区头部,约低越往后。 插入位置计算算法:

int index = (int) (proxies.size() * (ratio + (1 - ratio) * (1 - avProxy.getScore().getAvgScore())));
proxies.add(index, avProxy);

其中IP分值是一个0-1的小数。0表示分值最低,1表示分值最高。 所以如果分数为0,那么将会插入到候补区到尾部;如果分数为1,那么将会插入到候补区尾部

smartProxyQueue和普通队列的比较

可以明确的是,普通队列不能根据IP质量来调整IP使用的概率,如果一个IP一直不可用,普通队列方式可以快速触发他下线,因为每使用一次他就会失败一次,从而导致打分降低快速降低。这个时候因为smartProxyQueue调度低质量IP的概率小,这个低质量IP存在于IP池的时间也就更长了。 但是如果一个IP偶尔失败,但不是全部失败,那么普通队列里面,都是以相等的概率调度IP资源。没有做到高质量IP高调度概率。但是因为IP可用(没有达到下线临界值),所以IP一直在使用。这个场景就可以对比出普通队列smartProxyQueue的差别了。 假定有一批IP资源都是可用的,但是他们的质量有差别,也即同时存在质量好的IP和质量不太好的IP。普通队列对他的调度方式是公平的,高质量IP和低质量IP使用概率相同。但是对于smartProxyQueue来说,他的调度则不是公平的,因为失败将会导致队列顺序惩罚。惩罚之后距离下次被调度的可能性就会低一些。且惩罚力度是根据本IP连续一段时间的使用情况的打分而定的,所以失败率越大的IP惩罚力度越大、被调度的概率越小。

打分模型

对于打分,也是存在模型的。所以,首先需要考虑IP分数的定义是什么?衡量一个IP质量的标准。我们可以想到衡量IP的分量可以包括IP稳定程度(请求不失败)、IP响应速度、IP匿名性等等。 但是在使用代理IP的时候,最重要的是IP稳定程度。dungproxy-client对IP质量的评估只使用了IP稳定程度。

然后需要考虑的是,什么样的IP是稳定的。失败一次就不稳定了吗?失败两次?三次?整体失败次数?整体失败率?连续一段时间内的失败次数和失败率?

显而易见,我们说IP稳定,是指在一定时间内,IP的失败率低。很容易想到,我们需要记录最近n次IP的使用情况,然后统计失败率。这里需要一个队列,在次数没有达到n的时候,插入到队列。在达到n次之后,删除尾部数据,将新记录插入达到队列头部。然后根据当前容器记录情况计算分值。 问题是,如果n有点大,应该怎么办。

所以dungproxy有一个设计特点,在需要一致性的时候,可以放弃一致性而达到一个相对模糊的趋势值。

dungproxy的打分模型描述如下:

  1. 设定一个factor,为一个大于1的整数,表示将会对n次IP使用进行分值评估
  2. 设定一个初始分值score,为IP第一次使用的分值
  3. 在第二次使用同一个IP之后,评估连续factor次IP使用平均分值 算法为:score = (newScore + score * (factor -1))/factor;

本算法对连续n次IP使用的平均分数计算不是绝对精确的,但是肯定是接近的。同时他的好处是不需要保存任何历史数据即可算出结果

打分特别说明,根据dungproxy-client定义,IP分数需要做归一化处理。也就是IP的分数需要在0-1之间,如果自定义打分策略对分数空间的定义不在0-1,那么需要归一化处理将其映射到0-1的数值空间

Java
1
https://gitee.com/goodhans/proxyipcenter.git
git@gitee.com:goodhans/proxyipcenter.git
goodhans
proxyipcenter
proxyip_old1
master

搜索帮助