登录  | 加入社区

黑狼游客您好!登录后享受更多精彩

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

查看: 802|回复: 0

可恶的爬虫直接把生产6台呆板爬挂了!

[复制链接]

952

主题

952

帖子

0

现金

黑狼菜鸟

Rank: 1

积分
0
发表于 2020-12-24 03:14:51 来自手机 | 显示全部楼层 |阅读模式 来自 法国

原标题:可恶的爬虫直接把生产 6 台呆板爬挂了!

作者 | 码农二胖 责编 | 张文

头图 | CSDN 下载自视觉中国

fX7K78iD8iJ2gITM.jpg

媒介

正在昼寝,忽然收到线上疯狂报警的邮件,检察这个邮件发现这个报警的应用近来半个月都没有发布,应该不至于会有报警,但是照旧打开邮件通过监控发现是由于某个接口流量暴增,CPU 暴涨。

为了先办理题目只能先临时扩容呆板了,把呆板扩容了一倍,题目得到临时的办理。

末了复盘为什么流量暴增?由于近来新上线了一个商品列表查询接口,重要用来查询商品信息,展示给到用户。业务逻辑也比力简朴,直接调用底层一个 soa 接口,然后把数据举行整合过滤,排序保举啥的,然后吐给前端。

这个接口平常流量都很安稳。线上只摆设了 6 台呆板,面临这骤增的流量,只能举行 疯狂的扩容来办理这个题目。 扩容呆板后题目得到临时的办理。厥后颠末哀求分析,原来大批的哀求都是无效的,都是爬虫过来爬取信息的。

这个接口其时上线的时间是裸着上的也没有思量到会有爬虫过来。

办理办法

既然是爬虫那就只能通过反爬来办理了。本身写一套反爬虫体系,根据用户的风俗,哀求特性啥的,欣赏器 cookie、同一个哀求频率、用户 ID、以及用户注册时间等来实现一个反爬体系。

直接接入公司现有的反爬体系,必要按照它提供的文档来提供指定的格式哀求日记让它来分析。既然可以或许直接用现成的,又何须本身重新造轮子呢。

末了决定照旧接纳接入反爬体系的爬虫组件。爬虫体系提供了两种方案如下:

方案 1:

睁开全文

爬虫体系提供批量获取黑名单 IP 的接口(getBlackIpList)和移除黑名单 IP 接口(removeBlackIp)。业务项目启动的时间,调用 getBlackIpList 接口把全部 IP 黑名单全部存入到当地的一个容器内里(Map、List),中心会有一个定时使命去调用 getBlackIpList 接口全量拉取黑名单(黑名单会及时更新,大概新增,也大概淘汰)来更新这个容器。

每次来一个哀求先颠末这个当地的黑名单 IP 池子,查验 IP 是否在这个池子内里。假如在这个池子直接返回爬虫错误码,然后让前端弹出一个复杂的图形验证码,假如用户输入验证码乐成(爬虫根本不会去输入验证码),然后把 IP 从当地容器移除,同时发起一个异步哀求调用移除黑名单 IP 接口(removeBlackIp),以防下次批量拉取黑单的时间又拉入进来了。然后在发送一个 activemq 消息告诉其他呆板这个 IP 是被误杀的黑名单,其他呆板担当到了这个消息也就会把本身容器内里这个 IP 移撤除。

实在同步关照其他呆板也可以通过把这个 IP 存入 redis 内里,假如在掷中容器内里是黑名单的时间,再去 redis 内里判定这个 ip 是否存在 redis 内里,假如存在则阐明这个 ip 是被误杀的,应该是正常哀求,下次通过定时使命批量拉取黑名单的时间,拉取完之后把这个 redis 内里的数据全部删除,大概让它天然逾期。

这种方案 :性能较好,根本都是操纵当地内存。但是实现有点贫苦,要维护一份 IP 黑名单放在业务体系中。

UEtAYAteprtd9DiT.jpg

方案 2:

爬虫体系提供单个判定 IP 是否黑名单接口 checkIpIsBlack(但是接口耗时有点长 5s)和移除黑名单 IP 接口(removeBlackIp)。每一个哀求过来都去调用爬虫体系提供的接口(判定 IP 是否在黑名单内里)这里有一个网络哀求会有点耗时。

假如爬虫体系返回是黑名单,就返回一个特别的错误码给到前端,然后前端弹出一个图形验证码,假如输入的验证码精确,则调用爬虫体系提供的移除 IP 黑名单接口,把 IP 移除。

这种方案: 对于业务体系利用起来比力简朴,直接调用接口就好,没有业务逻辑,但是这个接口耗时是没法忍受的,严峻影响用户的体验。

终极综合思量下来,末了决定接纳方案 1。究竟体系对相应时间是有要求的只管不要增长不须要的耗时。

方案 1 实现

方案 1 伪代码实现,对于读多写少的线程安全的容器我们可以选择 CopyOnWrite 容器。

staticCopyOnWriteArraySet blackIpCopyOnWriteArraySet = null; /*** 初始化*/@PostConstructpublicvoidinit { // 调用反爬体系接口 拉取批量黑名单List< String> blackIpList = getBlackIpList; // 初始化blackIpCopyOnWriteArraySet = newCopyOnWriteArraySet(blackIpList); }

/*** 判定IP 是否黑名单* @param ip* @return*/publicbooleancheckIpIsBlack( Stringip) { booleancheckIpIsBlack = blackIpCopyOnWriteArraySet.contains(ip); if(!checkIpIsBlack ) returnfalse; // 不在redis白名单内里if(!RedisUtils.exist( String.format( "whiteIp_%", ip)){ returnfalse; } returntrue; }

上线后颠末一段时间让爬虫体系消耗我们的哀求日记,颠末肯定模子特性的练习,结果照旧很显着的。

由于大部门都是爬虫许多哀求直接就被拦截了,以是线上的呆板可以直接缩容掉一部门了又回到了 6 台。

但是好景不长,忽然发现 GC 次数频仍告警不停。为了临时办理题目,赶紧把生产呆板举行重启(生产出题目之后,除了重启和回退另有什么办理办法吗),而且保存了一台呆板把它拉出集群,重启之后发现过又是一样的照旧没啥结果。

通过 dump 线上的一台呆板,通过 MemoryAnalyzer 分析发现一个大对象就是我们存放 IP 的大对象,存放了大量的的 IP 数目。这个 IP 存放的黑名单是放在一个全局的静态 CopyOnWriteArraySet,以是每次 gc 它都不会被接纳掉。只能暂时把线上的呆板设置都举行升级,由原来的 8 核 16g 直接变为 16 核 32g,新呆板上线后结果很明显。

为啥测试情况没有复现?测试情况原来就没有什么其他哀求,都是内网 IP,几个黑名单 IP 照旧开辟手动构造的。

办理方案

业务体系不再维护 IP 黑名单池子了,由于黑名单来自反爬体系,爬虫黑名单的数目不确定。以是 末了决定接纳方案 2 和方案 1 联合优化。

项目启动的时间把全部的 IP 黑名单全部初始化到一个全局的布隆过滤器

一个哀求过来,先颠末布隆过滤器,判定是否在布隆过滤器内里,假如在的话我们再去看看是否在 redis 白名单内里(误杀用户必要举行洗白)我们再去哀求反爬体系判定 IP 是否是黑名单接口,假如接口返回是 IP 黑名单直接返回错误码给到前端;假如不是直接放行(布隆过滤器有肯定的误判,但是误判率黑白常小的,以是纵然被误判了,末了再去现实哀求接口,如许的话就不会存在真正的误判真实用户)。假如不存在布隆器直接放行。

假如是被误杀的用户,用户举行了 IP 洗白,布隆过滤器的数据是不支持删除(布谷鸟布隆器可以删除(大概误删)),把用户举行精确洗白后的 IP 存入 redis 内里。(大概一个当地全局容器,mq 消息同步其他呆板) 下面我们先来相识下什么是布隆过滤器吧。

什么是布隆过滤器

布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的。 它现实上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个聚集中。它的长处是 空间服从和查询时间都远远凌驾一样平常的算法,缺点是有肯定的误辨认率和删除困难。

上述出自百度百科。说白了布隆过滤器重要用来判定一个元素是否在一个聚集中,它可以利用一个位数组简便的表现一个数组。它的空间服从和查询时间远远凌驾一样平常的算法,不外它存在肯定的误判的概率,实用于容忍误判的场景。假如布隆过滤器判定元素存在于一个聚集中,那么大概率是存在在聚集中,假如它判定元素不存在一个聚集中,那么肯定不存在于聚集中。

实现原理

布隆过滤器的原理是,当一个元素被参加集适时,通过 K 个散列函数将这个元素映射成一个位数组(Bit array)中的 K 个点,把它们置为 1 。检索时,只要看看这些点是不是都是 1 就知道元素是否在聚集中;假如这些点有任何一个 0,则被检元素肯定不在;假如都是 1,则被检元素很大概在(之以是说“大概”是偏差的存在)。

底层是接纳一个 bit 数组和几个哈希函数来实现。

Fls8nSvwqslw00AP.jpg

kztt0GZpkYx8y0yw.jpg

下面我们以一个 bloom filter 插入"java" 和"PHP"为例,每次插入一个元素都举行了三次 hash 函数。

java 第一次 hash 函数得到下标是 2,以是把数组下标是 2 给置为 1;java 第二次 Hash 函数得到下标是 3,以是把数组下标是 3 给置为 1;java第三次 Hash 函数得到下标是 5,以是把数组下标是 5 给置为1;PHP 第一次 Hash 函数得到下标是 5,以是把数组下标是 5 给置为 1 ...

查找的时间,当我们去查找 C++ 的时间发现第三次 hash 位置为 0,以是 C++ 肯定是不在不隆过滤器内里。但是我们去查找“java”这个元素三次 hash 出来对应的点都是 1。只能说这个元素是大概存在聚集内里。

布隆过滤器添加元素

  • 将要添加的元素给 k 个哈希函数

  • 得到对应于位数组上的 k 个位置

  • 将这 k 个位置设为 1

将要添加的元素给 k 个哈希函数

得到对应于位数组上的 k 个位置

将这 k 个位置设为 1

布隆过滤器查询元素

  • 将要查询的元素给 k 个哈希函数

  • 得到对应于位数组上的 k 个位置

  • 假如 k 个位置有一个为 0,则肯定不在聚集中

  • 假如 k 个位置全部为 1,则大概在聚集中

将要查询的元素给 k 个哈希函数

得到对应于位数组上的 k 个位置

假如 k 个位置有一个为 0,则肯定不在聚集中

假如 k 个位置全部为 1,则大概在聚集中

引入 pom

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version> 23.0</version> </dependency>

publicstaticintcount = 1000000; privatestaticBloomFilter<String> bf = BloomFilter.create(Funnels.stringFunnel(Charset.forName( "utf-8")), count, 0.009); publicstaticvoidmain( String[] args) { intmissCount = 0; for( inti = 0; i < count; i++) { bf.put(i+ ""); }for( inti = count; i < count+ 1000000; i++) { boolean b = bf.mightContain(i + ""); if(b) { missCount++;}}System. out.println( newBigDecimal(missCount).divide( newBigDecimal(count))); }

办理题目

布隆过滤器先容完了,我们再回到上述的题目,我们把上述题目通过伪代码来实现下;

/*** 初始化*/@PostConstructpublicvoidinit { // 这个可以通过设置中央来读取double fpp = 0.001; // 调用反爬体系接口 拉取批量黑名单List< String> blackIpList = getBlackIpList; // 初始化 不隆过滤器blackIpBloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.forName( "utf-8")), blackIpList.size, fpp); for( Stringip: blackIpList) { blackIpBloomFilter.put(ip);}}/*** 判定是否是爬虫*/publicbooleancheckIpIsBlack( Stringip) { booleancontain = blackIpBloomFilter.mightContain(ip); if(!contain) { returnfalse; }// 不在redis白名单内里if(!RedisUtils.exist( String.format( "whiteIp_%", ip)){ returnfalse; } // 调用反爬体系接口 判定IP是否在黑名单内里}

总结

上述只是枚举了通过 IP 来反爬虫,这种反爬的话只能应对比力低级的爬虫,假如轻微高级一点的爬虫也可以通过署理 IP 来继承爬你的网站,如许的话本钱大概就会加大了一点。

爬虫固然好,但是照旧不要乱爬。“爬虫爬的好,牢饭吃到饱”。

步伐员怎样制止陷入“内卷”、选择什么技能最有远景,中国开辟者近况与技能趋势毕竟是什么样?快来到场「2020 中国开辟者大观察」,更有丰富奖品送不绝!

滴滴开源的丧失!章文嵩将去职,曾是阿里开源“赶集人”,投身开源 20 年

☞ 红帽急了:新年的 RHEL 将有低本钱或免费版

不打不相识,苹果偷学微信代码

在看返回搜狐,检察更多

责任编辑:





上一篇:原创猿辅导作业帮广告翻车折射在线教诲企业的“三个粗放” ...
下一篇:iOS14.4准正式版发布:苹果参加非官方摄像头零件检测
您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

 

QQ|申请友链|小黑屋|手机版|Hlshell Inc. ( 豫ICP备16002110号-5 )

GMT+8, 2024-5-18 07:50 , Processed in 0.175378 second(s), 61 queries .

HLShell有权修改版权声明内容,如有任何爭議,HLShell將保留最終決定權!

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表