第十一章 消息队列

我们知道,爬虫的性能瓶颈许多时候都是网络 I/O。但即便是优化了网络 I/O,爬虫还是会出现长时间的(抓取)解析模块空闲的情况。产生这个现象的原因在于写入数据库比抓取解析要慢的多。通过分析,是写入数据库的性能跟不上抓取解析的性能,为了让两边的速率达成平衡,我们可以引入消息队列。

1. 什么是消息队列

消息队列(Message queue)是一种进程间通信或同一进程的不同线程间的通信方式。消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的数据,包含发生的时间,输入设备的种类,以及特定的输入参数,也就是说:消息的发送者和接收者不需要同时与消息队列互交。消息会保存在队列中,直到接收者取回它。 ——维基百科

上面的解释比较官方,我们就以图中的模型为例进行说明:

  • Producer:生产者,负责产生和发送消息到 Broker;
  • Broker:消息处理中心。负责消息存储、确认、重试等,一般其中会包含多个 queue;
  • Consumer:消费者,负责从 Broker 中获取消息,并进行相应处理;

通过消息队列的模型,我们可以发现消息队列可以说是生产者/消费者模型的一种实例化。通过引入消息队列机制,我们可以让我们的程序拥有以下特性:

(1) 异步性

将耗时的同步操作,通过以发送消息的方式,进行了异步化处理。减少了同步等待的时间。

(2) 松耦合

消息队列减少了服务之间的耦合性,不同的服务可以通过消息队列进行通信,而不用关心彼此的实现细节,只要定义好消息的格式就行。

(3) 分布式

通过对消费者的横向扩展,降低了消息队列阻塞的风险,以及单个消费者产生单点故障的可能性(当然消息队列本身也可以做成分布式集群)。

(4) 可靠性

消息队列一般会把接收到的消息存储到本地硬盘上(当消息被处理完之后,存储信息根据不同的消息队列实现,有可能将其删除),这样即使应用挂掉或者消息队列本身挂掉,消息也能够重新加载。

2. 在爬虫之中使用消息队列

在消息队列机制之中,一般有2种模式:

  1. 队列模式 消息生产者生产消息发送到queue中,然后消息消费者从queue中取出并且消费消息。消息被消费以后,queue中不再有存储,所以消息消费者不可能消费到已经被消费的消息。Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。

  2. 主题模式 消息生产者将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。和队列模式不同,发布到topic的消息会被所有订阅者消费。

在队列模式下,爬虫的抓取解析模块将数据提取出来后,发送请求给队列。而在主题模式下,存储模块通过订阅了topic来获取消息队列主动推送的有关抓取解析模块传递到消息队列的数据.消费信息后,两种模式都需要删除已经被消费过的消息,以便用来保证该数据不会被多次重复使用。

所以在添加了消息队列以后,整个爬虫的组件流程也会有相应的调整:

从这个流程之中,我们可以看到,子模块之间没有任何依赖关系,通过消息队列机制,我们实现了模块之间的相互隔离。这样即使其中一个模块出现问题,那也不会蔓延至整体。如果爬虫因为没有数据而停滞,我们可以通过布置多个节点来避免消息队列为空的问题。

results matching ""

    No results matching ""