• RabbitMQ笔记-保证消息100%投递成功


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

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

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

    防止消息被重复消费:

    可能出现重复消费的几种情况:
    生产者发送了多条一样的消息
    消费者成功处理消息后断网或宕机导致没有确认消息被消费,消息队列会再一次发送消息

    解决重复消费的方案:

    方案1:
    使用唯一MessageID判断消息是否被消费过,比如创建订单消息,可以用订单ID做MessageID、支付成功使用流水号做MessageID
    其他逻辑比如发货、退款、取消、备注等,可以加一个操作记录表,使用操作记录表ID做MessageID
    消费端需要同样有一个消费记录表,在消费消息时先判断MessageID是否已存在,如果已存在就不插入。
    也可以使用Redis,创建一个hash类型的缓存,订单号做key,MessageID做field,如果消费过,value为1
    方案2:
    使用Redis,与上面大致相同,消息消费前将MessageID作为key,通过redis防重,如果不存在就消费消息并添加redis缓存,如果key存在就丢弃消息

    Unacked消息怎么处理:

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

  • 相关阅读:
    Python3 collections模块的使用
    基于python的分治法和例题
    docker容器间通信 (共用宿主机)
    HTML之form表单ENCTYPE属性解析
    搭建基于码云gitee平台代码自动部署
    centos7下docker搭建nginx+phpfpm环境
    mysql主从配置
    centos7升级自带mariadb
    linux下安装docker
    centos7安装postgreSql11
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/13274321.html
Copyright © 2020-2023  润新知