消息 100% 投递
1、消息落库,对消息状态进行打标
2、消息的延迟投递,做二次确认,回调检查
什么是可靠性投递?
1、保障消息的成功发出
2、保障mq节点的成功接收
3、发送端收到MQ节点确认应答
4、完善的消息进行补偿机制
注意:一般大厂不加任何事务,事务影响性能
消息堆积
处理方法:
1、默认消费者是单线程串行消费,所以可以通过设置 消费者并行消费
参数:
concurrentConsumers :并发消费者的个数
prefetchCountoncurrentConsumers:一次从borker里去消费的个数
2、增加消费者的处理能力,减少发布频率
3、使用消息队列最大长度限制
4、给消息设置年龄,超时丢弃
5、建立新的 queue,消费者同时订阅新旧 queue,采用订阅发布模式
6、生产者缓存数据,在 mq 被消费完后再发送到 mq ,打破发送循环条件,
设置合适的 qos 值,当 qos 值被用光,
而新的 ack 没有被mq 接受时,就可以跳出发送循环,接受新的消息
7、建立一个临时的分发数据的 consumer 程序,消费之后不做耗时处理,直接放在新创建的队列中,
然后让那些有耗时处理的消费者去处理这些业务
幂等性
每次操作的结果都是一致的
如何避免重复消费?
(唯一id+指纹码)
1、insert操作,给消息设定唯一性主键,就算消息重复消费,会发生主键冲突,避免数据库出现脏数据
2、redis的set 操作,set多次结果都是一样的
3、用redis做消息记录:
如果消息被消费过,则直接以的形式写入redis,
在消费之前查询消息有没有被消费过
好处:实现简单
坏处:高并发的时候数据库写入有瓶颈问题
解决方案:根据id进行分库分表,算法路由 redis的原子性幂等性
顺序性消费
为什么会产生消息乱序消费的问题?
三个消息发送到队列中,队列绑定了三个消费者1、2、3,分别收到了三个消息 A,B,C
要求是 A B C 按照循序消费,但是 由于消费者2处理能力强先处理完了,此时,消息消费就出现了问题
如何解决此问题:
1、三个消息都由一个消费者去消费
2、一个队列绑定一个消费者,消费者通过内存队列进行消息排队实现消息按序消费
推荐一个篇播客: Rabbitmq如何保证消息顺序执行 - -零 - 博客园 (cnblogs.com)