目录
MQ的作用以及场景
项目什么场景使用到了MQ,为什么使用MQ
RabbitMQ的作用以及使用场景
RabbitMQ的主要应用场景
消息队列解耦应用程序的例子
消息队列的应用场景
消息队列是接收消息和转发消息的,可以
1.异步解耦:业务流程中,一些操作kennel非常耗时,但是并不立马返回结果,可以借助MQ让他们异步话,比如说是用户注册发送短信通知,可以作为异步任务处理,无需等这些操作完成之后,再告诉用户注册成功(4399注册,直接就注册成功了,然后给你弹短信恭喜少爷注册成功)
2.流量削峰:比如还是xx男星公布恋情,访问量巨大,在平时没有这么大的访问量,如果因此当成标准去投入资源会很浪费,此时可以使用rabbitMQ,使用MQ可以使关键组件支撑突发访问压力,不会因为突发流量而崩溃,比如秒杀或者促销
3.(异步通信):支付订单里面取消支付,我们可以随时处理他,那就需要把消息放入MQ里面
4.延迟通知:特定时间发送通知场景,比如在电子商务平台,下单后一定时间未支付,可以使用延迟队列在超时后自动取消订单。
了解过哪些MQ区别
了解过哪些MQ,为啥不用其他的MQ
RabbitMQ,RocketMQ,ActiveMQ,Kafka,ZeroMQ等
1.Kafka
Kafka:一开始的目的是用于日志收集和传输,追求高吞吐量,性能卓越,单机吞吐十万级别日志领域十分成熟,功能比较简单,主要支持简单MQ,支持大数据处理,日志聚合,实时分析等场景
2.RabbitMQ:采用Erlang语言开发,MQ功能完备,支持几乎所有主流语言,开源界面友好,性能比较好,吞吐量到达十万级别,社区活跃度高,文档更新频繁,比较适合中小型公司,数据量没那么大,并发没那么高
3.RocketMQ
采用JAVA开发,可用可靠,稳定性都出色,吞吐量大,支持客户端语言不多,产品较新文档较少,社区活跃度一般,适合大规模分布式系统,可靠性要求高,且并发量大的场景,比如互联网金融
介绍RabbitMQ的核心概念以及工作流程
工作流程:生产者连接到Broker创建一个Connection,开启信道
2.声明交换机和队列,以及绑定规则:Producer声明一个交换久(Exchange)和队列,并且绑定Queue到Exchange
发布消息:Producer发布Broker
消息存储:RabbitMQ Broker接收消息,并且存入相应的队列中,如果未找到相应的队列,则根据生产者的配置,选择丢弃或者退回生产者
5.消费消息:消费者监听Queue,当消息到达时候,从Queue中获取消息,处理后向RabbitMQ发送消息确认
6.消息删除:消息被确认后,RabbitMQ会把消息从Queue中删除
RabbitMQ如何保证消息可靠性
Rabbit消息丢失原因及其方案,
如何保证消息不丢失,
消息写入失败怎么办,
消息消费失败如何处理
MQ的主动ack和被动ack区别
RabbitMQ如何解决数据丢失问题,如何保持一致性
消息队列如何保证消费者消息不丢失的
1.发送方投递可靠性
2.RabbitMQ可靠性
3.消费者可靠性
1)生产者到Broker,把消息发给交换机,网络抖动,使用发送方确认机制,收没收到返回一个ack,confirm模式,解决生产者到交换机这个方面
2)Exchange->Queue routing key不匹配使用return退回模式(如果有一条消息无法被任何队列消费)
3)队列设置长度,超过长度了,就给死信
2.Broker本身出现问题,MQ挂了,采用持久化,队列持久化,仲裁队列
3.Broker->Consumer:消费者确认,
自动确认:消息到达消费者,如果消费者逻辑有问题,处理失败,会导致消息丢失
手动确认:消费者需要清楚告诉我们消费完事,给我们一个ack.
RabbitMQ如何保证消息顺序性
消费端内部实现消息排序逻辑
局部和全局的顺序性保证
1.全局顺序性保证:
首先要有一个唯一序号,并且可以进行排序,然后再去存储。
2.局部顺序性:同一个ID,进行分区,不同消费者消费不同的队列,
3.消息确认机制:处理完一条消息后,再去显示发送确认,这样RabbitMQ才会移除并且继续发送下一条消息
RabbitMQ如何保证消息消费时的幂等性
RabbitMQ怎么保证消息不重复消费,消息或请求存在重复消费问题吗?是怎么解决的?
怎么解决MQ重复消费问题.
幂等性保障:可以被多次应用,而不去改变初始应用的结果,对一个系统重复调用,不管请求多少次,对系统影响都是一样的。
全局唯一ID,给每条消息设置唯一ID,根据ID,在消费之前,判断消息是否消费过,之前没有消费过,进行处理,处理完成后,保存ID,假如之前消费过,放弃处理。
业务逻辑判断
比如消费过,消费中,暂退款等状态。
RabbitMQ介绍死信队列
首先什么是死信:死信就是无法被正常消费的消息
死信队列:就是接收那些无法被正常消费等信息,在消息队列系统中,如rabbitMQ,死信队列用于存储这些死信消息
死信队列的来源:
消息设置了存活时间(TTL):超过规定ttl
消息被拒绝:消费者处理消息时,可能因为消息内容错误处理逻辑异常等原因拒绝该消息,如果拒绝时候指定不重新入队,消息也会变成死信.
队列设置了规定长度,满了溢出,新来的消息变成死信
死信队列的应用场景
死信队列时可以处理异常情况下,消息不能够消费者正常消费而被置入死信队列中的情况,应用程序可以通过消费这个死信队列中的内容来分析当时遇到的异常情况,进而可以改善和优化系统
比如说是用户支付订单,返回当前订单的支付状态
为了保证支付消息不丢失,需要使用死信队列机制,当消息消费异常的时候,将消息投入到死信队列中,由订单系统的其他消费者来监听这个队列,并且对数据进行处理
场景还有:
消息重试,把死信消息重新发送到原队列或者另一个队列进行重试处理
消息丢弃:直接丢弃这些无法处理的消息,以避免他们占用系统资源
日志收集:将死信队列作为日志收集,便于日后分析问题和定位。
延迟队列
概念:延迟队列是一个特殊的队列,消息发送之后并不立即给消费者,而是等待特定的时间才发送给消费者,延迟队列的应用场景很多:
十分钟内未支付自动取消
用户注册成功之后,3天后发调查问卷
用户发起退款,24小时商家未处理默认同意自动退款。
通过TTL+死信队列可以完成一个延时队列的。
或者是RabbitMQ给的原装插件
二者对比
基于死信队列实现的延迟队列:
灵活不需要额外插件支持
缺点:存在消息顺序性问题,需要额外的逻辑来处理死信队列的消息,增加了系统的复杂性
2.基于插件实现的延迟队列
优点:通过插件可以直接创建延迟队列,简化延迟消息的实现,避免了死信队列实现的延迟队列中的时序性问题
缺点:需要特定的插件,以及特定的版本
RabbitMQ的工作模式
simple简单模式。 一个生产者,一个消费者
work Queue工作队列 一个生产者多个消费者
Public/Subscribe(发布订阅模式):广播的一个模式
Routing(路由模式):根据RoutingKey转发特定的队列
Topics(通配符模式):根据通配符转发队列
RPC(RPC通信):并不常用
Publisher Confirm(发布确认)
消息积压问题
消息生产过快
消费者能力不足
网络问题
RabbitMQ服务配置偏低
解决方案:提高消费者效率,比如增加机器,优化业务逻辑,限制消费者生产速率,资源配置优化。
RabbitMQ是推模式还是拉模式
Push/pull
推模式:消息中间件主动推送给消费者 @RabbitListener
拉去消息:消费者主动从中间件拉取消息rabbitmq.receive()
RabbitMQ基于推模式工作的,核心设计是让消息队列中消费者接收到由生产者发送的消息,使用channel.basicConsume方法订阅队列,RabbitMQ就会把消息推送到订阅该队列的消费者,如果只想从队列中获取单条消息而不是持续订阅,则可以使用channel.basicGet方法来消费消息。
推模式:
对消息的获取更加实时,适合对数据实时性比较高,比如实时数据处理,监控系统,报表系统等
拉模式:消费端可以按照自己的处理速度来消费,避免消息积压,适合需要流量控制,或者大量计算资源的任务,拉取模式允许消费者在准备好后,再请求消息,避免资源浪费。