文章目录
- 应用场景
- 选型
- 高可用
- RabbitMQ
- 镜像集群模式
- Kafka
- 重复消费
- 接口幂等
- 强校验
- 弱校验
- 消息丢失
- RabbitMQ
- 生产者在消息传入过程中数据丢失
- RabbitMQ消息丢失
- 消费者消息丢失
- 顺序消费
- 问题
- 解决
- 消息堆积
- 过期失效
- 参考
应用场景
- 异步处理:
- 应用解耦:
- 流量削峰:
- 应用解耦:
选型
- 吞吐量:ActiveMQ和RabbitMQ都是万级,RocketMQ和Kafka是十万级
- 时效性:Rabbit是微秒级,其他是毫秒级
- 可用性:ActiveMQ和RabbitMQ是主从架构,RocketMQ和Kafka是分布式架构
- 可靠性:ActiveMQ有较低概率丢失数据
- 功能支持:ActiveMQ功能完备,RabbitMQ基于erlang开发,并发能力强,延时低,RocketMQ分布式,扩展性好,Kafka功能简单,主要用于大数据领域
高可用
RabbitMQ
镜像集群模式
- 通过管理控制台新增镜像集群模式策略,可以指定数据同步到所有节点,再次创建queue时,自动将数据同步到其他节点
- 数据同步到所有节点需要性能开销
- 扩展性差
Kafka
afka 一个最基本的架构认识:由多个 broker 组成,每个 broker 是一个节点;你创建一个 topic,这个 topic 可以划分为多个 partition,每个 partition 可以存在于不同的 broker 上,每个 partition 就放一部分数据。
这就是天然的分布式消息队列,就是说一个 topic 的数据,是分散放在多个机器上的,每个机器就放一部分数据。
重复消费
消息队列一般会被多个下游业务监听,如果其中某个下游业务发生异常,会触发消息队列的重试机制,消息队列会重新发送消息,这样正常执行的业务就面临重复消费的问题。
接口幂等
在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。
幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。
强校验
业务每次收到消息,首先去相关的业务流水表进行校验是否已经存在处理过,如果没有则继续执行业务,适用于重要业务场景
弱校验
业务处理消息,将处理结果也就是唯一流水号和相关信息存储在Redis中,业务收到消息,首先去Redis中校验,如果没有则继续执行业务,适用于不重要业务场景
消息丢失
RabbitMQ
生产者在消息传入过程中数据丢失
- 开启事务,同步阻塞,不推荐
- 开启confirm模式。生产者向MQ写入消息时会返回一个ack,如果RabbitMQ没有处理这条消息会返回一个nack。异步,推荐
RabbitMQ消息丢失
- 设置持久化
- 创建队列时将其设置为持久化
- 发送消息时将
deliveryMode
设置为 2
消费者消息丢失
关闭RabbitMQ的自动ack,在程序中处理完成后手动ack
顺序消费
问题
解决
创建多个队列,每个队列对应一个消费者,消费者内部再用内存队列做排队。
消息堆积
紧急扩容:
- 消费侧出了问题,先停掉消费侧,让其修复
- 新建临时队列,十倍于原先的队列数量
- 写一个临时的分发消费程序,将堆积的消息轮询分发到临时创建的队列中
- 临时征用十倍于原来的机器部署消费侧程序,加速消费堆积消息
- 快速消费完成后恢复原本部署的架构
过期失效
批量重导,先丢弃数据,后期手动查出来,补入队列中
参考
https://doocs.github.io/advanced-java/#/./docs/high-concurrency/mq-interview
https://github.com/AobingJava/JavaFamily/blob/master/docs/mq/%E9%87%8D%E5%A4%8D%E6%B6%88%E8%B4%B9%E3%80%81%E9%A1%BA%E5%BA%8F%E6%B6%88%E8%B4%B9%E3%80%81%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1.md