【RabbitMQ.Client笔记】如何保证消息100%投递成功

如何保证消息100%投递成功:

保证消息投递成功需要在生产者、消息队列、消费者3个环节控制

  • 消息队列
    消息队列需要将交换器、队列、消息持久化,防止因断电等问题导致数据因没有持久化而丢失
  • 生产者
    生产者需要确保消息发送到消息队列,需要使用事务消息确认的方式可以确保数据发送成功,推荐使用消息确认方式。如果发送失败要安排重试
    每个重要消息都应该在发送之前持久化到数据库,消费成功就更新消息状态,失败就安排重试。
  • 消费者
    默认情况下消费者在收到消息后会自动消息确认(ack),如果消费者在收到消息后程序异常,导致消息并没有成功消费。所以需要将自动确认改成手动确认,等成功消费消息后再确认。

补充:如果队列服务器断电、宕机怎么处理:
有可能消息没来得及持久化就断电,而且生产者此时没办法将消息发送到队列,所以消息发到消息队列之前持久化到数据库。使用服务定时获取消息状态,重新发送失败的消息

防止消息被重复消费(幂等性)

消费者成功处理消息后断网或宕机导致没有确认消息被消费,消息队列会再一次发送消息

方案

使用唯一MessageID判断消息是否被消费过,比如创建订单消息,可以用订单ID做MessageID、支付成功使用流水号做MessageID
其他逻辑比如发货、退款、取消、备注等,可以加一个操作记录表,使用操作记录表ID做MessageID
消费端需要同样有一个消费记录表,在消费消息时先判断MessageID是否已存在,如果已存在就不插入。

Unacked消息怎么处理:

未ack的消息状态会变为Unacked,客户端断开连接后,状态会变为Ready

posted @ 2020-07-26 16:46  .Neterr  阅读(827)  评论(0编辑  收藏  举报