【基本概念】消息队列

750 阅读4分钟

在计算机科学中,消息队列是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。

消息队列

消息队列的定义

消息队列(Message Queue)是一种进程间或同一进程内不同线程的通信方式,是一个消息代理器(Message Broker)。

在计算机科学中,消息队列(Message queue)是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的资料,包含发生的时间,输入设备的种类,以及特定的输入参数,也就是说:消息的发送者和接收者不需要同时与消息队列交互。消息会保存在队列中,直到接收者取回它。 -- 消息队列 - 维基百科,自由的百科全书 (wikipedia.org)

消息队列的特点

  • 异步
    消息队列允许消费者在消息发送很长时间后再取回消息。

    优点是生产者在投递信息之后可以直接处理其他信息而不需要阻塞等待消费者的处理;缺点是消费者必须轮循消息队列,才能接收到最新的消息。

    例如 A 系统接收一份加密数据需要解密并进行存储,这个过程是非常漫长的。如果 A 系统将数据投送到消息队列,由 B 系统向消息队列订阅并获取消息进行处理,此时 A 系统可以直接处理其他任务。

    消息队列的异步这一特点常被应用于流量削峰处理,削峰属于高并发概念,峰表示请求高峰,此时容易让网络服务因资源不足而崩溃,削峰就是解决这个问题,属于对异步特点的应用。

    例如 A 系统平均每分钟请求数为 500,最大承受请求数为 2000,但每天 18 点固定会有 5000 个请求的请求高峰。此时如果提高 A 系统性能将最大请求书扩大至 5000,则会造成非常大的性能浪费。如果将 A 服务拆分为生产端和消费端,生产者将接收的请求投递到消息队列中,消费者向消息队列订阅消息,消费者可以以 2000 请求正常速度进行处理。此时生产者依旧可以接收新的请求,超出承受能力的请求暂时积压在消息队列中,等高峰期过后,积压的消息会开始减少。

  • 解耦
    消息队列可以把信息的创建和处理逻辑拆分到不同进程中处理,使得消息的处理不会对消息的生产者造成影响。

    例如 A 系统创建的数据需要传递给 B、C 系统处理,如果 B 系统下线,A 系统需要修改代码逻辑。如果 A 系统将数据投送到消息队列中,让 B、C 向消息队列订阅消息。此时无论 B 系统下线还是新增 D 系统,都不影响 A 系统的执行。

通信

消息队列的本质是一种通讯方式,或者说是一种通讯工具,处于消息发送方与接收方中间。通过存储消息的方式实现了异步通讯,使得消费者不必在消息发送时就立即处理消息;通过中间协调的方式,使得消息者不必关心生产者的操作和状态,生产者也不必关心消费者的操作和状态,从而实现解耦。

消息队列的缺点

  • 提高系统复杂度

  • 降低系统可用性
    随着系统的依赖与模块的增加,必将增大系统出现问题的风险,引入消息队列这一模块,就会降低整体系统的可用性。

  • 存在一致性隐患
    消息队列的生产者与消费者处于隔离状态,如果多个消费者处理同一条消息并存储处理结果,可能出现某个消费者处理失败而导致数据不一致的情况。

常用消息队列

  • ActiveMQ
    ActiveMQ 是比较早期出现的消息队列,由 Apache 进行维护,由 Java 实现。

  • RabbitMQ
    RabbitMQ

  • RocketMQ
    RocketMQ

  • Kafka
    Kafka

  • Redis Stream
    Redis Stream