nodejs抓取动态网页(1.为什么需要一个前端监控系统?技术选型监控的意义)
优采云 发布时间: 2022-02-05 01:20nodejs抓取动态网页(1.为什么需要一个前端监控系统?技术选型监控的意义)
1. 为什么需要前端监控系统
通常大型web项目中会有很多监控系统,比如后端服务API监控、接口存活、调用、延迟等监控,一般用于监控后端数据级别的信息界面。而对于大型的网站系统,从后端服务到前端展示会有很多层:内网VIP、CDN等。
但是这些监控并不能准确反映用户看到的前端页面的状态,比如页面上第三方系统数据调用失败、模块加载异常、数据不正确、天窗茫然地打开。
这时候就需要从前端 DOM 展示的角度去分析采集用户真实看到的东西,从而检测页面是否存在异常问题。
2. 监控系统需要解决的问题
当页面出现以下问题时,您需要及时通过邮件或短信方式向相关人员报告,以解决问题。
3. 技术选型
监控的含义和测试的含义本质上是一样的,都是对已经上线的功能进行回归测试,但不同的是监控需要长期持续的、反复出现的回归测试,而测试之后只需要做一次发射,市场投入。回归测试。
由于监控和测试的性质是相同的,我们可以用测试的方法来做监控系统。在自动化测试技术遍地开花的时代,有很多有用的自动化工具,我们只需要整合这些自动化工具供我们使用。
节点JS
NodeJS 是一个 JavaScript 运行环境,NodeJS 支持非阻塞 I/O 和异步、事件驱动,这对于我们构建基于 DOM 元素的监控更为重要。
幻影JS
PhantomJS 是一个基于 webkit 的 JavaScript API。它使用 QtWebKit 作为其核心浏览器,并使用 webkit 来编译、解释和执行 JavaScript 代码。它可以做任何你可以在基于 webkit 的浏览器中做的事情。
它不仅是一个不可见的浏览器,提供诸如 CSS 选择器、对 Web 标准的支持、DOM 操作、JSON、HTML5、Canvas、SVG 等,它还提供处理文件 I/O 的操作,让您可以读写文件到操作系统等。PhantomJS的用途很广泛,比如网络监控、网页截图、免浏览器网页测试、页面访问自动化等等。
为什么不使用硒
做自动化测试的同学一定了解 Selenium。可以使用Selenium在浏览器中执行测试用例,Selenium对各种平台和常见浏览器的支持都很好,但是Selenium上手难度稍大,使用Selenium需要在服务器端安装浏览器。
考虑到监控的主要任务是监控而不是测试。系统不需要过多考虑兼容性,监控功能也比较简单,主要针对页面的功能回归测试,所以选择了PhantomJS。
4. 架构设计架构概述
架构如下图所示。
(点击放大图片)
架构简介
对于 DOM 监控服务,在应用层面做了纵向划分:
应用层面的垂直划分,实现应用的分布式部署,提升处理能力。后期的性能优化、系统改造和扩展也可以提高简单性。
5. 解决方案(1) 前端规则入口
这是一个独立的Web系统。系统主要用于采集用户输入的页面信息,页面对应的规则,显示错误信息。通过调用后端页面爬取服务完成页面检测任务,通过系统可以创建三种检测页面:定期监控、高级监控、可用性监控。
日常监测
输入一个页面地址和几个检测规则。注意这里的检测规则,我们将一些常用的检测点抽象成一个类似测试用例的语句。每个规则用于匹配页面上的一个 DOM 元素,并使用 DOM 元素的属性来匹配预期。如果匹配失败,系统会产生错误信息,并交由报警系统处理。
匹配类型一般有这些类型:长度、文本、HTML、属性
处理器类似于编程语言中的运算符:大于、大于或等于、小于、小于或等于、等于、正则。
这样做的好处是,输入规则的人只需要知道一点 DOM 选择器的知识就可以上手。在内部,我们通常将规则交给测试工程师完成输入。
高级监控
主要用于提供高级页面测试功能,测试用例一般由经验丰富的工程师编写。这个测试用例写起来会有一定的学习成本,但是可以模拟网页操作,比如点击、鼠标移动等事件。以实现对页面信息的准确抓取。
可用性监控
可用性监控侧重于即时监控页面可访问性、内容正确性等更严重的问题。通常我们只需要在程序中启动一个Worker,不断获取页面的HTML来检测和匹配结果,所以我们选择NodeJS做异步页面爬取队列来高效快速的完成这种网络密集型任务。
(2)主动报错页面脚本执行错误监控
页面引入监控脚本,采集页面产生的错误事件信息,并自动上报给后端服务。在系统中可以汇总所有的错误信息,以及对应的客户端浏览器版本、操作系统、IP地址等。
活动页面报告
该功能需要对应的前端工程师调用代码中的报错API主动提交错误信息。主要使用场景包括,页面异步服务延迟无响应、模块降级、主动通知等。监控脚本提供了几个简单的API来完成这个任务。
// error 方法调用后立即上报错误信息并发出邮件、短信通知
errorTracker.error('错误描述')
// info 方法调用后立即上报信息,并在单位时间内仅仅产生一条邮件、短信通知
errorTracker.info('信息描述')
// log 方法调用后由报错检测是否达到设置阀值,最终确认是否报错
errorTracker.log('日志信息')
(3)后端页面抓取服务
由于京东的很多页面内容是异步加载的,而首页、单品等系统有很多第三方异步接口调用,后端程序抓取的页面数据是同步的,动态JavaScript渲染的数据不能获得。所以你必须使用像 PhantomJS 这样可以模拟浏览器的工具。
对于日常监控,我们使用 PhantomJS 模拟浏览器打开页面进行爬取,然后将监控规则解析成 JavaScript 代码片段执行并采集结果。
对于高级监控,我们使用 PhantomJS 打开页面,将 jasmine、Mocha 等前端 JavaScript 测试框架注入到页面中,然后在页面上执行相应的输入测试用例并返回结果。
常规队列*敏*感*词*
规则队列*敏*感*词*会将规则系统采集的规则转换成消息队列,然后交给长期持久化处理器进行顺序处理。
为什么要使用类似消息队列的处理方式?
这与 PhantomJS 的性能是分不开的。通过多次实践发现,PhantomJS 不能很好的进行并发处理。当并发量过多时,CPU会过载,导致机器宕机。
对于本地环境的虚拟机并发测试,数据并不理想,限制基本在ab -n 100 -c 50左右。所以为了防止并发带来的问题,我们选择使用消息队列来进行避免高并发导致服务不可用。
类似消息队列的实现
这里我们通过调用内部分布式缓存系统来生成一个消息队列。队列的产生其实可以参考数据接口——队列。最基本的模型是在缓存中创建一个KEY,然后根据队列数据结构的schema插入和提取数据。
当然消息队列的中间介质可以根据你的实际情况选择,当然你也可以使用原生内存实现。这可能会导致应用程序和类似消息队列的内存争用。
长效处理器
长期持久处理器是由消费规则队列*敏*感*词*生成的消息队列。
长效处理实施
在长时持久化处理器的具体实现中,我们充分利用了JavaScript的setInterval方法,不断的获取疲倦消息队列的内容并发送给规则转换器,再转发给负载均衡调度器。之后统一处理返回的结果,如邮件或短信报警。
API
PhantomJS服务可以作为公共API提供给客户端处理测试需求,通过HTTP调用API。在 API 的处理中,需要提供 HTTP 数据到规则和 PhantomJS 的转换。因此,HTTP 数据到规则的转换器得到了发展。
PhantomJS 服务
PhantomJS 服务是指将 PhantomJS 与 HTTP 服务和子进程相结合的服务处理