重启服务器消息队列丢失,rabbitMQ--防止消息丢失

1.在生产端,可以通过comfirm机制,让生产端获悉消息已被MQ接收(接收不成功则重发)。

2.消息被消费者领了,并且消费者设置了autoAsk(我拿了数据,你队列就把数据删了吧),但消费者运行一半之后崩了,导致的消息丢失。

解决办法:

//消费者消费消息

public static void main(String[] args) throws Exception {

//获取连接和通道

Connection connection = ConnectionUtil.getConnection();

Channel channel = connection.createChannel();

//声明通道

channel.queueDeclare(QUEUE_NAME,false,false,false,null);

//这里设置成true的话,那在队列取消息后,队列会马上将消息从队列删掉

//这个自己按场景判断要不要设置为true

boolean autoAck = false;

channel.basicConsume(QUEUE_NAME, autoAck, "myConsumerTag1",

new DefaultConsumer(channel) {

@Override

public void handleDelivery(String consumerTag,

Envelope envelope,

AMQP.BasicProperties properties,

byte[] body)

throws IOException

{

try{}

catch (Exception e){}

finally {

long deliveryTag = envelope.getDeliveryTag();

//autoAck设置为false的话,这里就一定要回应一下队列,否则消息会一直驻留在消息队列不会删除,导致内存泄露

channel.basicAck(deliveryTag, false);

}

System.out.println(consumerTag+"接收消息 : "+new String(body));

}

});

}

另外说明一点,如果消息消费完了,准备执行channel.basicAck的时候,消费端崩了。此时MQ发现这个消费者崩了,把消息发给另一个消费者消费,导致了重复消费问题。这个需要根据自身的场景判断用什么解决方案,比如我这边是生产者提交订单,消费者进行一系列动作“创建订单”,消费者多个,我在数据库保存有deliveryTag参数(消息的唯一标识 ID),每个消费消息前,都看看这个ID有没被insert到数据库,有则说明该消息已被消费,直接channel.basicAck即可。

3.rabbitMQ服务器宕机,导致队列里面的数据丢失

使用消息持久化:

在上述代码的channel.queueDeclare里面的第二个参数durable设置为true,那么队列就会被持久化,消息宕机重启也能恢复。

案例场景:

订单系统有订单,需要传给仓库系统做拣配。

这里不搞消息确认那一套,直接用代码解决问题。

订单发送给MQ时,订单状态设为“待拣配”,仓库系统拣配完成后,发消息到MQ,订单系统将订单状态改为“已拣配”。系统后台维护一个线程,如果发现一个订单1小时还未拣配,就再发送消息给MQ,如此保证消息绝对会被处理,不会丢失。

bacb29c0c38c

image.png

这个机制就像是:只要你仓库系统一天不回我信息,我就打爆你手机。

这么一来,整个消息过程不需要任何ack机制,直接跑就行。这么做,也间接解决了,消息在MQ宕机丢失的问题(连消息持久化都不用搞了)。

这套方案,在一对一的消息传递还是好使的,一对多的情况(订单系统对仓库系统+支付系统)就比较麻烦,也许这些时候,就要老老实实地ack,并且思考MQ宕机导致消息丢失的补偿方案了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值