36

高性能网站实用技巧之消息队列篇

 4 years ago
source link: https://www.tuicool.com/articles/6NJjEjy
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

什么是消息队列

aeqY733.png!web

消息队列( Message Queue )是一种进程间通信或同一进程的不同线程间的通信方式。进程或者线程之间通过 消息 进行通信,消息发送后可以立即返回,由消息系统来确保信息的可靠传递,消息发布者(生产者)只管把消息发布到消息队里中而不用管谁来消费,消息使用者(消费者)只管从消息队列中获取消息以进一步处理而不用管理谁发布的消息,这样发布者和使用者都不用知道对方的存在。

消息( Message )是指在应用之间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以很复杂,如嵌入对象。

消息队列的特点

通过提供 消息传递消息排队 模型,它可以在 分布式环境 下提供 应用解耦弹性伸缩冗余存储流量削峰异步通信数据同步 等等功能,其作为 分布式系统架构 中的一个重要组件,有着举足轻重的地位。消息队列主要特点有:

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

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

  • 分布式:通过对消费者的横向扩展,降低了消息队列阻塞的风险,以及单个消费者产生单点故障的可能性。

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

消息队列应用场景

异步处理

同步处理是指从请求的发起一直到最终的处理完成期间,请求的调用方一直在同步阻塞等待调用的处理完成。

异步处理处理是指在请求发起的处理过程中,客户端的代码已经返回了,它可以继续进行自己的后续操作,而不需要等待调用处理完成。

对一些比较耗时且不需要即时(同步)返回操作结果的操作,可以把处理过程通过消息队列进行异步处理。这样做可以推迟耗时操作的处理,使耗时操作异步化,而不必阻塞客户端程序,客户端的程序在得到处理结果之前可以继续执行,从而提高客户端程序的处理性能。

异步处理的主要目的是 减少请求响应时间 ,实现非核心流程异步化,提高系统响应性能。

应用解耦

使用消息队列,可以有多个生产者发布消息,多个消费者消费消息,共同完成整个的业务处理逻辑,生产者只关心是否正确将消息写入消息队列,消费者只关心从消息队列中获取消息,然后进行处理逻辑,生产者和消费者之间不需要直接的交互调用,没有代码的依赖耦合。

耦合度越低程序代码越容易维护,也容易进行扩展。

流量削峰

一般在秒杀活动中广泛使用。

在秒杀活动中,一般由于瞬时访问量过大,服务器瞬间接收了大量的请求,流量暴增,这种情况下很有可能导致相关系统无法处理请求甚至崩溃。为了解决这个问题,一般会在应用的前端加入消息队列。

  • 请求先写入消息队列,而不是由业务系统直接处理,做了一次缓冲,极大的减少了业务处理系统的压力。

  • 队列的长度可以做限制,一般秒杀活动都是有数量限制的,后写入队列的用户无法秒杀到商品,这样的请求可以直接被抛弃,可以直接返回活动已结束或商品已售完。

使用消息队列,即便是访问流量持续的增长,系统依然可以持续的接收请求。虽然生产者生成的消息比消费者消费的速度快,但是通过消息队列进行了缓冲,在短时间内,生产者和消费者之间处理能力不会互相影响,同样也可以保证系统的稳定性。

消息通讯

消息队列一般都内置了高效的通信机制,因此可以用于单纯的消息通讯,比如实现点对点消息队列或者聊天室。

广播

如果没有消息队列,每当一个新的业务方介入,那都需要联调一次接口。有了消息队列,只需要关系消息是否送达了队列,至于谁希望订阅,是下游的事情,无疑极大地减少了开发和联调的工作量。

日志处理

将消息队列用在日志处理中,解决了大量日志传输的问题(如Kafka)。

消息队列的传输模式

点对点模式(Point to Point)

点对点模式用于 消息生产者消息消费者 之间 点到点 的通信。消息生产者将消息发送到由某个名字标识的特定队列( Queue )。在消息传递给消费者之前它被 存储 在这个队列中。 队列消息 可以放在 内存 中也可以 持久化 ,以保证在消息服务出现故障时仍然能够传递消息。

aYfqEnn.png!web

点对点模式特点:

  • 每个消息只有一个消费者(Consumer),即一旦消息被消费,消息就不再在消息队列中。

  • 生产者和消费者之间没有依赖性,生产者发送消息之后,不管有没有消费者在运行,都不会影响到生产者下次发送消息。

  • 消费者在成功接收消息之后需向队列应答成功,以便消息队列删除当前接收的消息。

发布/订阅模式(Publish/Subscribe)

发布者/订阅者模型支持向一个特定的 消息主题 生产消息。 0 或多个 订阅者 可能对接收来自 特定消息主题 的消息感兴趣。

在这种模型下,发布者和订阅者彼此不知道对方。多个消费者可以获得消息,在 发布者订阅者 之间存在 时间依赖性 。发布者需要建立一个 订阅subscription ),以便能够消费者订阅。 订阅者 必须保持 持续的活动状态接收消息

Ezmiqi3.png!web

发布/点阅模式特点:

  • 每个消息可以有多个订阅者。

  • 发布者和订阅者之间有时间上的依赖性,针对某个主题(Topic)的订阅者,它必须创建一个订阅之后,才能消费发布者的消息。

  • 为了消费消息,订阅者需要提前订阅该角色主题,并保持在线运行。

集中消息中间件对比

目前在生产环境,使用较多的消息队列有 ActiveMQRabbitMQZeroMQKafkaMetaMQRocketMQ 等。

ZfIJniu.jpg!webnuUvMnZ.jpg!web

好文推荐:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK