分布式事务的一种方案:消息可靠性 + 最终一致性, 那么
如何保证消息的可靠性?
1. 消息丢失(最重要)
消息丢失:如何保证消息不丢失?
1.1. 网络原因发不出-> 记录日志+定时任务处理
比如网络原因发布出去:怎么弄? catch异常重新while(true)发几次?NoNoNo! 如果是网络原因, 很可能发不出去,
正确做法:
- 数据库建一个mq_message的表, 每发一条mq消息都记录到库;
- 定时任务扫, 状态是 "未发送成功" 的记录, 重新发送;
1.2 Broker持久化失败->生产者发送确认+失败重发
我们的消息都要设置持久化保存, 我们成功将消息发送到mq的Broker,但是broker需要将消息持久化, 然后才能进入到queue里, 这个中间mq挂了, 怎么保证消息不丢失?
Producer-->(Broker(Exchange)-->(Queue))-->Consumer
我们使用生产者发送者的确认机制: 只有发送到broker, broker持久化完成消息抵达送给队列以后, broker才会给发送者确认;这样就能保证发送成功
1.3 Consumer消费丢失->关闭自动确认, 使用手动ACK
MQ消费时宕机或消费失败?关闭消费时自动确认, 使用 手动manual ACK, 消费完确认!
2. 消息重复
2.1 消息重复的2种情形:
比如消费者消费消息, 收到了两遍
- consumer消费失败, 手动basicReject拒绝了, 这种是允许的;
consumer消费完成,手动ACK之前突然宕机, 此时没给broker确认消息消费完成;这样, 就有可能会再发给其他的消费者,造成消息重复;
消费成功,ack宕机,消息由 unack变为ready, 然后broker会重新发送
宗旨: 设计消费时, 做到 幂等消费
2.2 幂等消费
2.2.1 消费做状态判断
业务设置状态, 消费时做状态判断, 处理过就忽略
2.2.2 防重表:唯一标识
防重表:发送的每一个消息都有唯一标识, 处理过就忽略
3. 消息积压
消息积压会带来MQ性能的下降, 所以一定要解决消息积压的问题
3.1 消息积压的3种原因
3.1.1 消费者宕机
3.1.2 消费者本身消费能力不足
3.1.3 发送者流量太大
3.2 解决消息积压的方案
3.2.1 限制业务流量+限制发送流量(下策)
3.2.2 上线更多的消费者, 加大消费规模
3.2.2.3 若消费逻辑复杂,可以设置:先纯消费-记录数据库-离线处理
可以处理mq压力, 转移mq压力
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。