zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Go分布式爬虫笔记(八)

2023-09-11 14:16:28 时间

08_项目需求分析与架构设计

需求分析

  • 业务需求

    • 爬虫引擎为基础的推送系统

    • 提供

      • 快速的热点事件
      • 事件预警
  • 用户需求

    • 快速了解自己感兴趣的最新新闻
    • 事件预警机制
    • 帮助快速决策
  • 功能需求

    • 用户填写或选择自己感兴趣的话题、感兴趣的网站还有消息接受频率
    • 用户接收最新热点事件的推送
    • 用户通过点击获取与该事件关联的事件,并得到相关的事件预测、预警,甚至可能在网站中进行快速的交易
    • 用户可以查看历史记录,可视化呈现某一个事件的来龙去脉,并进行复盘
  • 产品需求

    • 前端页面设计

    • 用户交互设计

    • 后端爬虫引擎设计

      • 爬取数据
      • 数据收集
      • 数据清洗
      • 数据存储
    • 数据分析设计

    • 数据推送设计

功能性模块分析

  • 数据输入

    • 种子网站: 提前规划好的新闻网站与论坛。
    • 用户通过界面和 API 接口动态增加或修改的任务。
  • 任务配置和管理

    • 读取配置文件中预先制定的任务列表
    • 存储后面用户动态新增的任务
    • 接口: 任务增删改查
    • 接口; 获取任务状态
  • 任务

    • 任务要爬取的 URL

    • 任务相关规则的描述

      • 抓取页面中的哪一些信息
      • 哪一些网址需要进行爬取
      • 页面爬取的深度
      • 请求超时时间
    • 规则引擎模块处理规则: 任务相关的规则可能比较复杂并且有关联,例如 A 网站爬取到 B 网站,B 网站爬取到 C 网站,每一个网站都需要有对应的处理规则。

  • 调度引擎

    • 任务均衡分发到采集模块
    • 接受任务存储到队列中
  • 采集引擎

    • 采集工作: 解析相应的页面信息.

    • 访问方式

      • 直接访问
      • 模拟浏览器访问
      • 提前登录
    • 采集算法

      • 深度优先搜索
      • 广度优先搜索
    • 任务回流调度引擎

  • 辅助任务管理模块

    • 限流器: 控制任务的采集频率
    • 代理器; 隐藏源IP, 突破服务器反扒机制
    • 去重器: 避免重复任务
    • 随机UA: 生成随机User-Agent
    • 任务优先级队列: 任务分级, 高优先级先执行
    • 失败处理器: 处理采集失败后的重试问题
  • 数据清洗和存储

    • 缓存队列: 收集一批数据后批量将数据写入数据库中.

    • 存储引擎

      • 存储到不同类型的数据库或文件中

​[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P88iGxhi-1679233104210)(https://assets.b3logfile.com/siyuan/1658627274984/assets/image-20230319210644-zuyxt7f.png)]​

非功能性模块设计

  • 扩展性

    • 服务能够随着任务数量的增加而扩展, 能够快速增加 Worker 程序的数量
    • Worker 服务是无状态的
    • 任务可以在任何 Worker 中运行,并且具有相同的行为。
  • 我们的任务将会在 Worker 中长时间存在,因此,我们会遇到许多新的问题:

    • 当我们增加一个新的 Worker,该怎么保证任务可以重新分配,或者确保新的任务一定能分配到新的 Worker 呢?
    • 每一个任务的负载是不同的,例如一些任务会比另一些任务消耗更多的 CPU 与内存。那么我们要如何合理分配任务,才能让每一个 Worker 负载均衡呢?
    • 解决: Master-Worker架构
  • 服务可用性 分布式系统容错问题

    • Master

      • 主要任务是完成调度工作,本身不需要实现多高的并发量,任务的调度和分配在一个程序中就能搞定。
      • 为了解决故障容错问题,我们需要有多个 Master 随时待命,这会需要对多个 Master 进行选主,客户端只能与 Master 的 Leader 节点进行交互,并且只有 Master 的 Leader 节点能够调度任务到 Worker。
    • Worker

      • 当 Worker 崩溃后,运行在其中的任务将无法运行。
      • Master 能够监控到 Worker 的数据变化,并且 Master 能够通过任务的重新分配将崩溃节点的任务分散到其他 Worker 中。
      • 当 Worker 重新恢复后也有类似的过程。不过由于 Worker 无状态,不用考虑 Worker 崩溃之后数据的不一致问题。
  • 分布式系统协调组件 etcd

    • 监听Worker节点
    • 服务发现
    • 任务动态分配
    • Master节点选主工作

​[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nasbhVOB-1679233104210)(https://assets.b3logfile.com/siyuan/1658627274984/assets/image-20230319211403-0guhuxa.png)]​

架构设计

  • Mater

    • 提供用户操作接口

      • 任务增删改查API
    • 任务调度器

      • 任务调度
      • 动态获取和监听Worker节点变化,实现任务动态的负载均衡
    • 借助etcd实现选主,实现可用性

    • 集群只有一个Leder,其他Master收到的请求会转发到Leader中处理

  • etcd

    • 为Worker与Master实现注册中心功能
    • 实现事件的监听和通知机制
    • 存储每个Worker需要执行的任务,由Master分配
    • 提供Master选主能力
  • Worker

    • 动态监听Worker分配的任务
    • 注册服务到etcd
    • 完成海量并发任务的爬取、解析、清洗、存储工作

​[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8jtxj71z-1679233104211)(https://assets.b3logfile.com/siyuan/1658627274984/assets/image-20230319211429-agja9xx.png)]​

实现细节

  • 框架与协议
  • 高并发模型
  • 程序扩展性设计

思考题

对 Go 这种静态编译的语言,你知道怎么在不重新编译和运行程序的情况下,动态添加一个新的爬虫任务和新的爬虫规则吗?

  1. 任务,通过用户界面添加到数据库里,然后任务调度器读取任务进行就好了。
  2. 规则,两种思路,如果可以将规则写成配置文件,如yaml,json之类的,那直接动态添加这个规则。但如果这个规则比较复杂,可以考虑为规则单独起一个服务,将服务配置到任务调度器里

「此文章为3月Day8学习笔记,内容来源于极客时间《Go分布式爬虫实战》,强烈推荐该课程!/推荐该课程」