消息队列-前言

一、消息队列

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

四、消息队列的主流产品

特性 RabbitMQ RocketMQ Kafka ZeroMQ Redis
核心定位 功能丰富、可靠的企业级消息代理 低延迟、高可靠、功能全面的金融级消息队列 高吞吐、持久化的分布式事件流平台 高性能、异步、轻量级的消息传递库 内存型、极高性能的数据结构服务器
吞吐量 十万级QPS 十万级QPS 百万级QPS 百万级QPS 极高(内存操作)
延迟 微秒级 毫秒级 毫秒级 毫秒级 微秒级
可靠性 高,基于主从架构实现高可用 非常高,分布式架构 非常高,分布式架构,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用 不是一个独立的服务,要嵌套到自己的程序里面去 依赖配置,RDB/AOF持久化会丢部分数据
数据模型 Queue + Exchange Queue + Topic 持久化日志,按主题-分区存储 Socket 多种数据结构,List/Stream/PubSub
顺序性 单个队列保证FIFO 分区内严格有序 分区内严格有序 不完全保证全局消息顺序 不保证
相关推荐
玄同76512 小时前
LangChain v1.0 中间件深度解析:从 Callback 到 Middleware 的演进
人工智能·语言模型·自然语言处理·中间件·langchain·agent·智能体
小邓吖1 天前
自己做了一个工具网站
前端·分布式·后端·中间件·架构·golang
Prince-Peng1 天前
技术架构系列 - 详解Redis
数据结构·数据库·redis·分布式·缓存·中间件·架构
Prince-Peng2 天前
技术架构系列 - 详解Kafka
分布式·中间件·架构·kafka·零拷贝·消息中间件·填谷削峰
爱吃山竹的大肚肚3 天前
异步导出方案
java·spring boot·后端·spring·中间件
GIS开发者3 天前
对nacos进行信创改造,将其中的tomcat替换为保兰德的中间件
java·中间件·nacos·tomcat·保兰德
晚风_END3 天前
postgresql数据库|连接池中间件pgbouncer的部署和配置详解
数据库·后端·spring·postgresql·中间件·个人开发
郑州光合科技余经理3 天前
同城配送调度系统实战:JAVA微服务
java·开发语言·前端·后端·微服务·中间件·php
321.。3 天前
从 0 到 1 实现 Linux 下的线程安全阻塞队列:基于 RAII 与条件变量
linux·开发语言·c++·学习·中间件