0%

消息队列之入门

[TOC]

两种模式

生产消费者模式(队列)

生产消费者模式,指的是由生产者将数据源源不断推送到消息中心,由不同的消费者从消息中心取出数据做自己的处理,在同一类别下,所有消费者拿到的都是同样的数据。是一种点对点的方式,消息不会被重复消费,可以粗暴的理解为消息被消费后就被标记删除或者已删除了,这是常见的消息队列通常的模式。比如说进程间通信,这种基于队列实现消息传输服务的。

队列下,就是每条记录被池子中的一个消费者消费。kafka中对队列的实现就是同一个消费者组下面的消费者就是队列式消费。

发布订阅模式

订阅发布模式,本质上也是一种生产消费者模式,不同的是,由订阅者首先向消息中心指定自己对哪些数据感兴趣,发布者推送的数据经过消息中心后,每个订阅者拿到的仅仅是自己感兴趣的一组数据(最简单的实现,就是多个topic)。这两种模式是使用消息中间件时最常用的,用于功能解耦和分布式系统间的消息通信。

相对于生产者 消费者模式,消息可能会被多方消费,可以简单的理解为一份报纸的内容,订阅它的人都可以读到它,当一个人读完之后也就没必要再次去读了。并且在发布订阅模式中,通常有个概念叫做topic,每个topic 有对应的发布者(publisher)、订阅者(subsciber)。发布订阅模式和设计模式中的观察者模式是一个思路,观察者订阅自己感兴趣的 topic, 然后 topic 有消息就得到通知。

发布订阅模式下,记录被广播到所有的消费者。kafka中对发布订阅的实现就是多个不同的消费者组同时消费同一个topic,多个consumer group 都能消费到每一条数据。但是kafka是多播。

kafka 中的单播和多播

单播

一条消息只能被某一个消费者消费的模式称为单播。要实现消息单播,只要让这些消费者属于同一个消费者组即可。当生产者发送一条消息时,同一消费者组中的多个消费者中只有一个能收到消息。

多播

一条消息能够被多个消费者消费的模式称为多播。之所以不称之为广播,是因为一条消息只能被Kafka同一个分组下某一个消费者消费,而不是所有消费者都能消费,所以从严格意义上来讲并不能算是广播模式,当然如果希望实现广播模式只要保证每个消费者均属于不同的消费者组。针对Kafka同一条消息只能被同一个消费者组下的某一个消费者消费的特性,要实现多播只要保证这些消费者属于不同的消费者组即可。然后通过生产者发送几条消息,可以看到不同消费者组的消费者同时能消费到消息,然而同一个消费者组下的消费者却只能有一个消费者能消费到消息。

消息解耦的优点

假设有一个用户行为采集系统,负责从App端采集用户点击行为数据。通常会将数据上报和数据处理分离开,即App端通过REST API上报数据,后端拿到数据后放入队列中就立刻返回,而数据处理则另外使用Worker从队列中取出数据来做,如下图所示。

BHIkFI.md.png

优点一:功能分离

功能分离,上报的API接口不关心数据处理功能,只负责接入数据

优点二:数据缓冲

数据上报的速率是不可控的,取决于用户使用频率,采用该模式可以一定程度地缓冲数据

优点三:易于扩展

在数据量大时,通过增加数据处理Worker来扩展,提高处理速率。这便是典型的生产消费者模式,数据上报为生产者,数据处理为消费者。

有点四:事件分发

假设有一个电商系统,那么,用户“收藏”、“下单”、“付款”等行为都是非常重要的事件,通常后端服务在完成相应的功能处理外,还需要在这些事件点上做很多其他处理动作,比如发送短信通知、记录用户积分等等。我们可以将这些额外的处理动作放到每个模块中,但这并不是优雅的实现,不利于功能解耦和代码维护。

我们需要的是一个事件分发系统,在各个功能模块中将对应的事件发布出来,由对其感兴趣的处理者进行处理。这里涉及两个角色:A对B感兴趣,A是处理者,B是事件,由事件处理器完成二者的绑定,并向消息中心订阅事件。服务模块是后端的业务逻辑服务,在不同的事件点发布事件,事件经过消息中心分发给事件处理器对应的处理者。整个流程如下图所示。这边是典型的订阅发布模式。

BHIEfP.md.png

参考

Kafka下的生产消费者模式与订阅发布模式