写点什么

架构设计之 MQ 选型

作者:无心水
  • 2021 年 12 月 14 日
  • 本文字数:2170 字

    阅读完需:约 7 分钟

架构设计之MQ选型

MQ 的好处

在微服务架构中,消息队列带来哪些好处呢


1. 改善写操作请求的响应时间:生产者写给队列即可返回,无需等待下游服务响应,缩短链路调用时间2. 更容易进行伸缩:小功能解偶为独立服务,更容易伸缩,提升处理能力3. 削峰填谷:控制消费速度,降低系统访问高峰压力4. 隔离失败:消费者处理消息失败,不会传递给生产者5. 降低耦合:上下游服务解藕6. 保证最终一致性
复制代码


常见 MQ 的模式

点对点模式

多个消息生产者向消息队列发送消息,多个消费者消费消息,每个消息只会被一个消费者消费


主题模式

多个消息消费者可以订阅同一个主题,每个消费者都可以收到这个主题的消息拷贝,然后按照自己的业务逻辑分别进行处理计算


常见开源的 MQ

  • ActiveMQ:Apache ActiveMQ® is the most popular open source, multi-protocol, Java-based message broker.

  • RocketMQ:Apache RocketMQ™ is a unified messaging engine, lightweight data processing platform.

  • RabbitMQ: RabbitMQ is lightweight and easy to deploy on premises and in the cloud. It supports multiple messaging protocols. RabbitMQ can be deployed in distributed and federated configurations to meet high-scale, high-availability requirements.

  • Kafka:Apache Kafka is an open-source distributed event streaming platform used by thousands of companies for high-performance data pipelines, streaming analytics, data integration, and mission-critical applications.


网上常见的对比:


Kafka VS RabbitMQ

从不同使用场景对比下 Kafka、 RabbitMQ


如何保证消息顺序一致性

  1. RabbitMQ:多个消息,分发不同的 QUEUE,导致顺序错乱。

  2. 需要保证顺序的消息,发同一个 Queue

  3. Kafka:生产者,发送同一个 KEY,消费者开启了多线程,导致顺序错乱

  4. 消费者加内存队列,既能保证高并发,又可以保证消费顺序

消息丢失

Kafka 消息丢失

Kafka 生产者丢失数据:leader 接收到了消息,尚未同步给 follower,leader 宕机。

设置 acks=all,一定不会丢。


要求是, leader 接收到消息,所有的 follower 都同步到了消息之后,才认为本次写成功了。


如果没成功,生产者会自动不断的重试,重试无限次。容易导致重复消费。

Kafka 自己丢失数据

设置四个参数


  • 设置 replication.factor 参数:这个值必须大于 1,要求每个 partition 必须有至少 2 个副本

  • min.insync.replicas 参数:这个值必须大于 1,这个是要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系

  • 在 producer 端设置 acks=all:这个是要求每条数据,必须是写入所有 replica 之后,才能认为是写成功了。

  • 在 producer 端设置 retries=MAX:这个是要求一旦写入失败,就无限重试,卡在这里了。

Kafka 消费者丢失数据:尚未消费消息就宕机

关闭自动 offset,启用手动 offset

RabbitMQ 消息丢失

RabbitMQ 生产者丢失数据

  • 网络丢包等故障。

  • confirm 模式,监听失败消息后无处理。

  • 发送的路由没有和 queue 绑定


  1. 事务机制:mq 没收到,异常报错,回滚事务。性能消耗大,同步阻塞,吞吐量降低。

  2. AMQP 协议提供的一个事务机制

  3. channel.txSelect()

  4. channel.txCommit()

  5. channel.txRollback()

  6. RabbitTemplate Confirm 确认机制 &Return 机制:callback 回调处理

  7. RabbitTemplate:定义 ConfirmCallback、ReturnCallback(消息无法路由到队列,消息回退)

  8. 需要先设置 rabbitTemplate.setMandatory(true)

  9. 分别对 confirmCallback 和 returnCallback 做回调处理

  10. 建立内存队列,指定消息唯一 ID,消息成功返回 ack 消息,失败会回调定义大 nack 接口

RabbitMQ 自己丢失数据:消息未完全持久化,机器重启

持久化设置


  • durable=True:queue 元数据持久化,

  • deliveryMode 为 2,将消息数据持久化

RabbitMQ 消费者丢失数据:尚未消费消息就宕机

关闭自动 ack,启用手动 ack

消息重复(保证消息幂等性)

Kafka 消息重复场景:消费完成,在准备提交 offset 时,还没提交,消费者重启


消息积压

基本措施:


  • 扩容。加个新 topic,定义多个 partion,消息转发到新 topic。增加消费者。

  • 消费者性能优化:异步解藕,提升处理能力


消息消费模式

1.rabbitmq 支持 PUSH、PULL


  • PUSH:及时性高,没考虑消费者处理能力

  • 默认 PUSH

  • PUSH 限流

  • 需要手动 ack。channel.basicAck

  • PULL:根据消费能力进行消费

  • 需要消费者手动调用


  1. kafka 只有 PULL

高可用

Rabbit MQ:非分布式 MQ

  • 单机模式

  • 普通集群模式

  • 基本架构

  • 优点:提升消费者吞吐量

  • 缺点:1.集群内部大量数据传输。2.没啥可用性保障,queue 所在节点宕机,会消息丢失。

  • 镜像集群模式

Kafka:分布式,保证 CA

  • 基本架构

  • 一个 topic 分为多个 partition,生产者可以指定数量。

  • 一个 partition 可以有多个副本,最少两个。replicat 分 leader,follower。

  • 生产者会向 leader 发送消息,follower 定期去 pull,收到后发送 ack 给 leader。可以指定写多少 replica,leader 发送 ack 给生产者。

  • acks=all,可以保证生产者不丢失数据,所有的 follower 都发送 ack 给 leader,leader 才发送 ack 给生产者,保证写成功。

  • leader 维护有 ISR(In Sync Replicas)列表,定时刷新。

参考

消息队列的介绍和常用开源消息队列的对比


RabbitMQ is the most widely deployed open source message broker.


More than 80% of all Fortune 100 companies trust, and use Kafka.


Flexible & Powerful Open Source Multi-Protocol Messaging


Apache RocketMQ™ is a unified messaging engine, lightweight data processing platform.

发布于: 1 小时前阅读数: 12
用户头像

无心水

关注

路漫漫其修远兮 2018.08.16 加入

熟悉Java,略懂Python

评论

发布
暂无评论
架构设计之MQ选型