一、消息队列

1.1、消息队列概述

消息队列,简而言之就是 消息 + 队列 (MessageQueue,简称MQ)

本质上是一种异步通信协议或中间件,其核心数据结构是队列,遵循先进先出(FIFO)原则,内容为消息

1.2、消息队列的用途

  1. 进程间通信
  2. 不同服务间通信

1.3、消息队列的应用场景

  1. 异步处理
  2. 流量控制
  3. 服务解耦
  4. 发布订阅
  5. 流量削峰/控制

1.4、为什么会有消息队列

在早期应用以及分布式系统架构中,各个服务之间调用,都是直接调用,或者通过RPC调用,服务之间耦合度太高,如果某个服务出现故障,整个系统都会受到影响。

比如用户的注册,注册服务需要调用到邮件服务,短信服务,支付服务等。

在这里插入图片描述

这种模式,会将所有服务都强耦合在一起,如果某个服务出现故障,整个系统都会受到影响。

  1. 系统脆弱,容错率低:
    1. 如果邮件服务突然宕机,那么注册服务也会失败或者宕机,导致整个系统受到影响。
    2. 也称为雪崩效应:一个非关键的服务故障,通过直接调用链扩散,导致整个关键业务不可用。注意和数据库的数据雪崩区分开来
  2. 系统性能瓶颈:
    1. 注册服务必须同步等待所有下游的服务全部完成之后,才能给用户反馈“注册成功”。整个过程耗时是所有服务耗时的总和,用户体验差。
  3. 系统扩展性差:
    1. 如果碰见大型活动,注册量突然暴增,邮件服务和短信服务可能无法承载这么大的流量,导致注册服务也跟着受影响,无法承载这么大的流量。

1.5、消息队列的引入

正是因为上述的痛点,所以需要引入一个中间人或公告栏,将各个服务进行解耦,从之前直接的、实时的调用,变为间接的,异步的调用。

在这里插入图片描述

  1. 解决性能瓶颈:
    1. 注册服务只需要将"用户已注册"这个消息快速写入到消息队列中,然后给用户反馈"注册成功",后续的邮件服务和短信服务等,通过异步的方式,从消息队列中获取到"用户已注册"这个消息,然后进行处理。
  2. 解决系统脆弱:
    1. 解耦:注册服务只依赖于消息队列,而不依赖邮件服务和短信服务等,即使邮件服务和短信服务等出现故障,也不会影响到注册服务。
    2. 削峰填谷:消息队列可以起到一个缓冲的作用,当流量暴增时,消息队列可以将这些请求缓存起来,然后慢慢处理,避免系统崩溃。高峰期的流量被削平,低峰期慢慢处理,这叫流量削峰
  3. 解决系统扩展性差:
    1. 如果碰见大型活动,注册量突然暴增,可以根据每个服务的实际压力来进行动态扩容,比如注册服务扩容2倍,邮件服务扩容3倍,短信服务保持不变。

二、核心术语和概念

2.1、生产者/发布者:

产生和发送消息的一方

2.2、消费者/订阅者:

接收和消费消息的一方

2.3、(Broker)代理:

接收生产者发送的消息,并将消息传递给消费者,简而言之就是消息队列的服务器; 主要具备以下职责:

  • 接收生产者发送的消息
  • 存储消息(内存/磁盘)
  • 路由消息(根据规则决定消息传递给哪个消费者)
  • 投递消息(将消息投递给消费者)

2.4、主题/Topic:

消息队列的分类,生产者发送消息到主题,所有订阅了该主题的消费者都会收到该消息的副本。

在这里插入图片描述

(发布/订阅模型示意图)

生产者产生消息,发送给Broker,Broker根据消息的主题,将消息投递给订阅了该主题的消费者。

2.5、消费者组

消费者组(Consumer Group)是由多个消费者组成的集合,同一个消费者组内的消费者共享一个消费队列,消费组内的消费者竞争消费消息,从而实现消息的负载均衡;

一个主题可以被多个消费者组订阅,实现真正的广播(发布/订阅)。

三、消息队列的架构模式

消息队列主要通过两种基本模型来组织消息的传递,分别是点对点模型发布订阅模型

3.1、点对点模型

  • 核心关系一对一,即一个生产者发送的消息,只能被一个消费者消费。
  • 类比任务队列,比如之前的单机无锁队列以及线程池当中的任务队列,一个任务只能被一个线程执行。
  • 工作流程:
    • 生产者产生消息,发送给Broker
    • Broker将消息存储到队列中,多个消费者监听队列
    • 队列中的每条消息,在任意时刻只能被其中一个消费者取走
    • 消费者处理完消息后,会告诉Broker该消息已经被处理,Broker会将该消息从队列中删除
  • 关键特性
    • 负载均衡:多个消费者共同消费一个队列中的消息,队列中的消息会被平均分配给多个消费者,提高处理能力
    • 消息独占性:保证一个任务只被执行一次
  • 产品代表:
    • ActiveMQ
    • RabbitMQ

3.2、发布订阅模型

  • 核心关系一对多。一个消息会被所有订阅了该主题的消费者都收到一份副本。

  • 类比:新闻广播或杂志订阅。出版社(生产者)发行一期杂志(消息),所有订阅了该杂志(主题)的读者(消费者)都会收到一本。

  • 工作流程:

    • 生产者将消息发布到某个主题。
    • 多个消费者可以订阅自己感兴趣的主题。
    • 消息到达主题后,会复制成多份,分别传递给所有活跃的订阅者。
  • 关键特性

    • 广播与解耦:生产者完全不知道有多少个、是哪些订阅者。新加入的订阅者可以收到之后的新消息。
    • 扇出处理:一个事件可以触发多个下游系统的并行动作。
  • 产品代表:

    • Kafka(核心模型)
    • Redis的Pub/Sub
    • RabbitMQ的Fanout Exchange

维度点对点发布订阅
核心目的分发任务,实现负载均衡广播事件,实现系统解耦与扇出
消息流向一个队列,多个消费者竞争一个主题,多个订阅者各得一份
消费者关系竞争关系,瓜分任务互不干扰

四、消息队列的主流产品

特性RabbitMQRocketMQKafkaZeroMQRedis
核心定位功能丰富、可靠的企业级消息代理低延迟、高可靠、功能全面的金融级消息队列高吞吐、持久化的分布式事件流平台高性能、异步、轻量级的消息传递库内存型、极高性能的数据结构服务器
吞吐量十万级QPS十万级QPS百万级QPS百万级QPS极高(内存操作)
延迟微秒级毫秒级毫秒级毫秒级微秒级
可靠性高,基于主从架构实现高可用非常高,分布式架构非常高,分布式架构,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用不是一个独立的服务,要嵌套到自己的程序里面去依赖配置,RDB/AOF持久化会丢部分数据
数据模型Queue + ExchangeQueue + Topic持久化日志,按主题-分区存储Socket多种数据结构,List/Stream/PubSub
顺序性单个队列保证FIFO分区内严格有序分区内严格有序不完全保证全局消息顺序不保证
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐