美文网首页
rabbitMQ--防止消息丢失

rabbitMQ--防止消息丢失

作者: 小狼在IT | 来源:发表于2019-04-30 10:42 被阅读0次

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,如此保证消息绝对会被处理,不会丢失。


image.png

这个机制就像是:只要你仓库系统一天不回我信息,我就打爆你手机。
这么一来,整个消息过程不需要任何ack机制,直接跑就行。这么做,也间接解决了,消息在MQ宕机丢失的问题(连消息持久化都不用搞了)。
这套方案,在一对一的消息传递还是好使的,一对多的情况(订单系统对仓库系统+支付系统)就比较麻烦,也许这些时候,就要老老实实地ack,并且思考MQ宕机导致消息丢失的补偿方案了。

相关文章

  • rabbitMQ--防止消息丢失

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

  • RabbitMQ防止消息丢失

    1.简介 RabbitMQ中,消息丢失可以简单的分为两种:客户端丢失和服务端丢失。针对这两种消息丢失,Rabbit...

  • mq防止消息丢失方案

    今晚,与老大交流了一下线程池接受出票异步反馈,老大告诉我,线程池耗内存而且当并发线程多了会造成堵塞,丢失关键数据...

  • PHP && RabbitMQ防止消息丢失

    RabbitMQ防止消息丢失,保证消息传递的可靠性,保证每条消息都正常传递,并最终至少消费一次。 背景:订单支付状...

  • WebSocket心跳机制

    为了防止websocket的 client和server由于各种原因锻炼造成消息丢失,必须定时向 server发送...

  • 消息队列-3 如何保证消息可靠性(RabbitMQ)

    消息丢失的场景 消息发送时消息丢失 路由消息时消息丢失 消息未持久化消息丢失 消费消息时消息丢失 消息发送可靠性 ...

  • MQ异步发送,那消息可靠性怎么保证?

    消息丢失可能发⽣在⽣产者发送消息、MQ本身丢失消息、消费者丢失消息3个⽅⾯。 ⽣产者丢失 ⽣产者丢失消息的可能点在...

  • 流与文件-流

    写在书上 保存下来防止丢失

  • kafka基础——消息不丢失

    内容 producer消息不丢失 consumer消息不丢失 生产端消息不丢失 不要使用 producer.sen...

  • RabbitMQ--交换机

    在上一篇文章[[RabbitMQ--初步了解]中,介绍了默认交换机,每个消息只分发给一个消费者。在本篇中,我们将把...

网友评论

      本文标题:rabbitMQ--防止消息丢失

      本文链接:https://www.haomeiwen.com/subject/milmnqtx.html