• RabbitMQ消息丢失、积压、重复等解决方案


    消息丢失

    1、只要订单完成我们就会发送一条消息给MQ,这个途中突然MQ服务器网络中断,导致消息无法抵达

    做好容错方法需要在消息发送前加上异常处理

     try {
      rabbitTemplate.convertAndSend("order-event-exchange", "order.release.other", orderTo);
        } 
    catch (Exception e) {
       //将没法送成功的消息进行重试发送
        }
    

    还可以将消息存入数据库,把失败的消息定期重新再发一遍

    2、当消息发送给MQ,通过Brock通过交换机抵达队列,MQ关机了,只有抵达队列才能实现消息持久化

    这时候需要使用生产者的确认机制

    image-20211021204726680

    只要消息收到了会自动持久化,如果进入另一个回调方法说明报错了,需要修改数据库使消息重发

    3、自动ACK的状态下。消费者收到消息,但没来得及消息然后宕机

    一定开启手动ACK,消费成功才移除,失败或者没来得及处理就noAck并重新入队

    消息重复

    1、消息消费成功,事务已经提交,ack时,机器宕机。导致没有ack成功,Broker的消息重新由unack变为ready,并发送给其他消费者

    image-20211021205648407

    在ack的时候宕机,导致消息没有确认,又需要重新发送

    2、消息消费失败,由于重试机制,自动又将消息发送出去

    image-20211021205941757

    关闭订单的时候,没有成功,又重新进入队列再次执行,这种是可以允许的

    解决办法:

    • 消费者的业务消费接口应该设计为幂等性的。比如扣库存有工作单的状态标志
    • 使用防重表(redis/mysql),发送消息每一个都有业务的唯一标识,处理过就不用处理
    • rabbitMQ的每一个消息都有redelivered字段,可以获取是否是被重新投递过来的,而不是第一次投递过来的

    image-20211021210504681

    判断当前消息是否是第二次及以后被派发过来的

    消息积压

    • 消费者宕机积压

    • 消费者消费能力不足积压

    • 发送者发送流量太大

      • 上线更多的消费者,进行正常消费

      • 上线专门的队列消费服务,将消息先批量取出来,记录数据库,离线慢慢处理

    这也是实现了柔性事务-可靠消息+最终一致性解决方案

    做好消息确认机制(生产者、消费者)+手动确认机制

    并把消息在数据库做好记录

  • 相关阅读:
    PHP页面跳转的几种方法
    PHP网站并发测试
    04-上传文件
    01-转>linux命令
    01-CDN的好处
    05-socket.io使用
    04-soket.io使用2 -数据同步简单聊天室效果
    03-socket.io 2.3.0版本的使用-用户请求接口,实时推送给前端数据
    02-转>
    跨域-转>预解析OPTIONS请求
  • 原文地址:https://www.cnblogs.com/cg-ww/p/15449768.html
Copyright © 2020-2023  润新知