谈谈那些欠下的技术债——消息队列

603 阅读7分钟

记住

摆烂太久是会被收走天赋的

消息队列

Redis 发布订阅(Pub/Sub)

Redis 发布订阅(Pub/Sub) 是一种基于消息通道的通信机制,适用于实时通知事件驱动系统

基本架构

  • 发布者(Publisher) :向 Redis channel 发送消息。
  • Redis 服务器:负责将消息广播到所有订阅该 channel 的客户端。
  • 订阅者(Subscriber) :监听 channel,收到消息后进行处理。

特点

  1. 发布订阅为实现推送,订阅者离线时,会错过所有未收到的消息
  2. 一个订阅者(Subscriber)可以监听一个或多个频道(Channel)。
  3. 一个频道(Channel)可以被多个订阅者(Subscriber)监听,订阅者之间互不影响,都会收到该Channel中推送的消息。可以理解为发布者对订阅者进行了广播。

使用场景

  • 实时 WebSocket 推送
  • 状态变更通知(订单状态变更、用户在线状态变更)

MQTT(Message Queuing Telemetry Transport)

MQTT 是一种轻量级的发布/订阅(Pub/Sub)消息传输协议,特别适用于 物联网(IoT)、消息推送、远程控制等低带宽、高延迟的网络环境。

基本架构

  • 发布者(Publisher):向 topic 发送消息。
  • Broker(服务器):如 MosquittoEMQX,负责管理 topic 和转发消息。
  • 订阅者(Subscriber):订阅 topic,收到对应的消息。

特点

  1. 轻量级、低带宽消耗

  2. 发布/订阅模式

  3. 支持 QoS(服务质量),确保消息可靠传输

    • QoS 0:最多一次,消息可能丢失。
    • QoS 1:至少一次,消息可能重复。
    • QoS 2:恰好一次,消息不丢失且不重复。

4- 持久会话、离线消息(断线重连后可接收未收到的消息)

5- 支持 TLS/SSL 安全加密

6- 跨平台

使用场景

  • 物联网(IoT)设备通信
  • 弱网环境数据传输
  • 远程控制

RabbitMQ

RabbitMQ 是一个基于 AMQP(高级消息队列协议)高性能消息队列,适用于任务队列、异步处理、微服务解耦等场景

基本架构

  • 生产者(Producer) :消息生产者是发送消息的应用程序或服务。

  • 消息队列(Queue):消息存储的地方。

  • 交换机(Exchange):交换机是消息的 路由器,负责将消息转发到一个或多个队列。

  • 消息消费者(Consumer):接收和处理消息的应用程序或服务。

  • 其他

    • 路由键(Routing Key):生产者在发送消息时附加的标识符,用于交换机在消息传递时的路由决策。
    • 绑定(Binding):交换机与队列之间的关联,定义了交换机如何路由消息到队列。
    • 消息确认(Acknowledgment):消费者告知 RabbitMQ 消息已成功消费的机制。
  1. Producer 生产消息并发送到 Exchange
  2. Exchange 根据路由规则将消息发送到 Queue
  3. Consumer 从队列中消费消息。

特点

  1. 支持多种消息模式

    模式交换机类型特点应用场景
    简单模式点对点通信简单任务分发
    工作队列模式多个消费者共享队列任务分发、负载均衡
    发布/订阅模式Fanout Exchange消息广播日志广播、事件通知
    路由模式Direct Exchange根据路由键精确匹配条件分发
    主题模式Topic Exchange根据路由键模式匹配复杂消息路由
    头部模式Headers Exchange根据消息头匹配基于属性的复杂路由
    RPC 模式支持同步通信需要响应的任务
  2. 支持消息持久化

  3. 支持确认机制

    1. 消费者确认(Consumer Acknowledgement)

      1. 自动确认(Auto-Ack)
      2. 手动确认(Manual-Ack)
    2. 生产者确认(Publisher Confirmation)

  4. 支持死信队列

  5. 高可用性 & 集群支持

使用场景

  • 异步任务处理
  • 应用解耦
  • 流量削峰

如何实现高可用

  1. 普通集群(提高吞吐量)

    创建的 queue,只会放在一个 RabbitMQ实例上,但是每个实例都同步 queue的元数据(元数据可以认为是 queue 的一些配置信息,通过元数据,可以找到 queue 所在实例)。消费的时候如果连接到了另外一个实例,那么那个实例会从queue所在实例上拉取数据过来。

  2. 镜像集群(高可用)

    创建的queue,无论元数据还是queue里的消息都会存在于多个实例上(每个 RabbitMQ节点都有这个queue的一个完整镜像),每次写消息到queue的时候,都会自动把消息同步到多个实例的queue上。

如何保证生产中RabbitMQ的高可用,看本文就够了【重点】_rabbitmq高可用方案-CSDN博客

RabbitMQ的高可用_rabbitmq高可用方案-CSDN博客

最佳实践

  1. 连接复用(避免每次发送消息都创建连接/通道),生产者和消费者使用独立的连接
  2. 为生产者设置合理的超时时间
  3. 避免开启自动消费确认,防止接收到消息后后续处理流程崩溃造成数据丢失
  4. 消费者幂等处理消息,防止重复消费
  5. 限制队列长度,避免大量堆积消息
  6. 合理的使用ConsumeGet 消费消息
  7. 消息持久化,避免消息丢失
  8. 开启镜像队列,实现高可用

消息队列 RabbitMQ 版 RabbitMQ 客户端实践教程-实践教程-文档中心-腾讯云

【进阶之路】消息队列——RabbitMQ原理(二)RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息 - 掘金

Kafka

Kafka 是一个分布式的流处理平台,主要用于高吞吐量、可扩展的消息队列和事件流处理。

基本架构

  • 生产者(Producer) :负责向 Kafka 主题(Topic)发送消息。

  • Broker(代理):负责存储和管理消息。

  • Partition(分区):一个 Topic 可以有多个分区,消息会被存储到不同的分区中,提高并发性能。

  • Replication(副本):每一个分区都有多个副本。当主分区(Leader)故障的时候会选择一个备胎(Follower)上位,成为Leader。在kafka中默认副本的最大数量是10个,且副本的数量不能大于Broker的数量,follower和leader绝对是在不同的机器,同一机器对同一个分区也只可能存放一个副本(包括自己)。

  • 消息队列(Queue):消息存储的地方。

  • 消息消费者(Consumer):接收和处理消息的应用程序或服务。

  • 其他

    • Topic(主题) :Kafka 的逻辑分组,生产者将消息发送到指定 Topic,消费者从 Topic 订阅消息。
    • Consumer Group(消费组) :将多个消费者组成一个消费者组,同一个分区的数据只能被消费者组中的某一个消费者消费,同一个消费者组的消费者可以消费同一个topic的不同分区的数据。
    • Zookeeper:保存集群的的元信息,来保证系统的可用性。
  • Kafka原理篇:图解kakfa架构原理-kafka原理

    Kafka基本原理详解(超详细!)-腾讯云开发者社区-腾讯云

特点

  1. 高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒
  2. 可扩展性:kafka集群支持热扩展
  3. 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失
  4. 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)
  5. 高并发:支持数千个客户端同时读写

使用场景

  • 日志收集

AWS SQS(Simple Queue Service)

Amazon SQS 最佳实践 - Amazon Simple Queue Service

延时队列

延时队列(Delayed Queue)是一种消息在指定时间后才能被消费的队列,适用于订单超时取消、支付超时、任务调度、重试机制等场景。

RabbitMQ

  1. 通过TTL(Time-To-Live)+ 死信队列(DLX)
  2. RabbitMQ Delayed Message Exchange 插件(延时交换机)

Kafka

  1. 定时轮询(Polling)
  2. 时间轮(TimeWheel)

Redis

  1. Zset(Sorted Set)

其他

  1. 轮询数据库
  2. 定时任务