0%

如何保证消息的可靠性

分布式事务的一种方案:消息可靠性 + 最终一致性, 那么

如何保证消息的可靠性?

1. 消息丢失(最重要)

消息丢失:如何保证消息不丢失?

1.1. 网络原因发不出-> 记录日志+定时任务处理

比如网络原因发布出去:怎么弄? catch异常重新while(true)发几次?NoNoNo! 如果是网络原因, 很可能发不出去,

正确做法:

  1. 数据库建一个mq_message的表, 每发一条mq消息都记录到库;
  2. 定时任务扫, 状态是 “未发送成功” 的记录, 重新发送;

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种情形:

比如消费者消费消息, 收到了两遍

  1. consumer消费失败, 手动basicReject拒绝了, 这种是允许的;

  2. 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压力