MQ三大重要特性:解耦,异步,削峰
RABBITMQ:
1.rabbitMQ有什么使用场景:
- 异步发送消息(邮件,验证码,短信)
- MYSQL,REDIS,ELASTICSEARCH之间的数据同步
- 分布式事务保持高可用性
- 削峰填谷
2.rabbitMQ如何保证消息不丢失?
在正常情况下publisher发送消息至exchange,exchange选择queue,再由queue将消息发送给consumer完成一次消息
- publisher->exchange
- 生产者确认机制:rabbitMQ提供了一个publisher confirm机制,当mq收到消息后,会给发送者提供一个回值表示消息处理成功
- 如果失败了,这里MQ会返回给publisher一个publisher-confirm NACK(NACK其实就是未路由的意思,没有找到路由)
- exchange->queue
- 如果失败了,这里MQ会返回给publisher一个publisher-return ACK(这里也是一种特殊的NACK,没有匹配到相应的queue,导致发送失败)
- 上述两种生产者发送消息失败,使用以下几种兜底方案:(失败一般就是两种情况:代码的问题,这个只能人工干预再修改;机器的问题,机器宕机了,可能是生产者也可能是MQ,这个就需要后续重新发送即可)
- 回调失败后立即重发
- 记录日志,后续补偿
- 保存消息至MySQL,然后定时重发,发送成功后删除表内的数据
- 持久化机制:确保在MQ内的消息不会丢失:可以在java中通过代码持久化exchange,queue和message。当然在springAMQP中message的持久化是默认的
- queue->consumer
- 消费者确认机制:消费者处理完消息后会给MQ一个回值ACK,MQ收到ACK后可以删除message
- springAMQP提供三种确认机制:
- manual:需要用户调用API返回ack
- auto(首选):spring监听listen是否有问题,自动返回ack
- none:mq会假定消息发送成功,消息投递后会立刻删除
- spring提供retry机制,消费者出现异常时调用本地重试机制,重试机制到达最大值后如果消息依旧发不出去,就会将消息放入errorExchange,转人工处理
3.rabbitMQ如何解决消息重复消费问题(幂等问题)
mq在网络抖动,消费者挂了的时候会出现重复消费
解决方案:
为消息设计一个唯一标识id(一般这个id是数据库里的一个unique);幂等方案:分布式锁,乐观锁,悲观锁
4.rabbitMQ中死信交换机(延迟队列)
延迟队列使用场景:超时订单、限时优惠、定时发布
延迟队列=死信交换机+TTL(生存时间)
死信条件:
- 消费者消费失败并且设置消息会成为死信
- 消息超过过期时间,仍然未消费(基于此可以实现延迟队列,消息本身、消息所在队列都可以设置一个存活时间TTL。两者取最小值。除此以外还可以使用delayExchange插件实现延迟队列)
- 投递的队列消息满了,最早的消息就可能会成为死信
死信交换机:需要在构造队列的时候声明队列的死信进入指定的dead letter exchange,并且该exchange也需要绑定对应的queue存储死信
使用DelayExchange插件后,不需要额外声明内容,只需要指定其为死信交换机,并设置x-delay即可
5.如何解决MQ大量消息堆积问题
什么是消息堆积问题:当生产者产生消息的速度超过了消费者,就会导致队列内的消息堆积,队列存储达到上限后。之后的消息可能会被丢弃,可能会成为死信
解决方案:
增加消费者,提高消费速度
消费者内开启线程池加快处理,
扩大队列容量,添加惰性队列(惰性队列就是消息不再存储至内存,转为磁盘可极大提高队列容量)
6.rabbitMQ的高可用机制
普通集群:
镜像集群:本质是主从模式。
- exchange,queue,message会在mq的各个镜像节点之间同步备份。
- 创建队列的节点被称为该队列的主节点,备份主节点叫该队列的镜像节点。
- 所有操作都是主节点先完成,再同步给镜像节点;主节点宕机会选用镜像节点作为新的主节点。
- 缺点是如果在同步的时候如果主节点宕机了,那么就可能会造成丢失数据。
仲裁队列:优化版的镜像集群,采用raft协议保证主从强一致性改善了镜像集群的缺点,而且配置简单:只需要在声明队列时加上.quorum()方法即可。
标签:速通,exchange,队列,RabbitMQ,queue,死信,消息,节点 From: https://www.cnblogs.com/kun1790051360/p/18414444