作用
1 解耦合,生产者和消费者之间解除耦合,通过消息队列中间件,多个生产者向同一个消息队列里写东西,消费者去拿东西
2 发布订阅模式,一个消息可以被多个消费者消费,如rabbitMq的topic
临时订阅,这种订阅只有在消费者启动并且运行的时候才存在。一旦消费者退出,相应的订阅以及尚未处理的消息就会丢失。
持久订阅,这种订阅会一直存在,除非主动去删除。消费者退出后,消息系统会继续维护该订阅,并且后续消息可以被继续处理。
3 削峰,通过中间件缓存功能,去实现该操作, 写入日志的时候,
4 异步调用, 发短信,邮件等
缺点
增加了系统的复杂性,需要高可用的消息队列来保证系统稳定
如果用异步的话,异常情况下的一致性问题
系统复杂性变高 可能发重复消息,导致插入重复数据;消息丢了;消息顺序乱了;系统 B,C,D 挂了,导致 MQ 消息积累,磁盘满了;
rabbitMQ
消息丢失
情况描述
1 生产者写消息的过程中,消息都没有到 rabbitmq,在网络传输过程中就丢了。或者消息到了 rabbitmq,但是人家内部出错了没保存下来
2 RabbitMQ 接收到消息之后先暂存在主机的内存里,结果消费者还没来得及消费,RabbitMQ自己挂掉了,就导致暂存在内存里的数据给搞丢了。
3 消费者消费到了这个消费,但是还没来得及处理,自己就挂掉了,RabbitMQ 以为这个消费者已经处理完了。
解决方案
1 事务机制或者confirm机制,去解决消息写入的方式
2 持久化到磁盘 创建queue的时候将其设置为持久化的,这样就可以保证 rabbitmq持久化queue的元数据,但是不会持久化queue里的数据发送消息的时候将 deliveryMode 设置为 2,将消息设置为持久化的,此时 rabbitmq就会将消息持久化到磁盘上去。必须同时设置 2 个持久化才行。持久化可以跟生产者那边的 confirm机制配合起来,只有消息被持久化到磁盘之后,才会通知生产者 ack了 ,所以哪怕是在持久化到磁盘之前 ,rabbitmq挂了,数据丢了,生产者收不到 ack,你也可以自己重发。<br>
3 关闭 autoAck,自己处理完了一条消息后,再发送 ack给 rabbitmq,如果此时还没处理完就宕机了,此时rabbitmq没收到你发的ack消息,然后 rabbitmq 就会将这条消息重新分配给其他的消费者去处理。
消息重复消费
1 insert操作,主键机制 ,重复插入报错
2 幂等操作,update操作,重复操作不影响
3 消息增加ID,消费前先查表
消息持久化条件
声明队列必须设置持久化 durable 设置为 true.<br>消息推送投递模式必须设置持久化,deliveryMode 设置为 2(持久)。<br>消息已经到达持久化交换器。<br>消息已经到达持久化队列。
缺点就是,必须持久化到磁盘,就牺牲了吞吐量,用的是磁盘而非内存存储
消息延迟策略
1 死信队列,建立一个死信队列来进行延时消息的收集(消息过期)
2 下载RabbitMQ-delayed-message-exchange插件去执行消息延迟发布,与headers有关
组件
2 消息交换器 exchange<br>
headerExchange
根据header进行匹配
角色
生产者
消息的创建者,负责创建和推送数据到消息服务器;
消息队列容器
就是 RabbitMQ 本身,用于扮演“快递”的角色,本身不生产消息,只是扮演“快递”的角色。
选型比较
吞吐量 rabbitMq<rocketMq<kafaka
延迟 rabbitmq<kafaka<rocketmq
高可用 rabbitmq基于主从 不如 racketmq和kafaka
消息的顺序处理,kafaka>rabbitmq
消息路由和过滤方面,rabbitmq>kafaka
消息时序 消息过期和延迟发送 rabbitmq>kafaka
灵活的路由规则 rabbitmq>kafaka
应用
1 发送短信,邮件。 客户交易股票程交之后,发送短信通知
2 异步操作,档案收集,解除耦合
3 约券管理,类似于库存管理,有异步和削峰饿概念
4 档案管理系统, 档案下载的时候