【消息队列】聊一下如何避免消息的重复消费

这篇具有很好参考价值的文章主要介绍了【消息队列】聊一下如何避免消息的重复消费。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是重复消费

一条消息在传输过程中,为了保证消息的不丢失,可能会多少量的消息进行重试,这样就可能导致Broker接受到的消息出现重复,如果说下游系统没有针对业务上的处理,那么可能导致同一笔借款或者支付订单出现重复扣款或者重复还款的情况。业务上是不允许出现的。
在MQTT 协议,给出了如下三种方式

  • 至多一次 (At Most Once) : 也就是针对每条消息即使出现异常的情况,也只会发送一次。应用场景:在一些硬件数据上传热点数据,可以使用。
  • 至少一次(At Least Once) : 为了保证消息不可靠传输,可能针对少量消息进行重复发送,那么就会出现同一个消息重复出现。
  • 恰好一次(Exactly Once) : 消息只会发送一次,不允许丢失也不会重复。

幂等性

幂等在计算机中是非常重要的概念,说白了就是多次执行一段函数的结果是一样的,比如说 * 1,那么 执行多次结果都是本身,但是如果是+1的操作,那么就不是幂等,每次结果都会加1。而数据库中增删改查,只有查是幂等,其他都会修改数据原有的状态。

在重试的场景下,我们一般都需要进行重试&幂等 进行配合使用,因为在数据在网络中传输,比如出现网络抖动,数据丢包以及挖掘机挖断网线(开玩笑😝了)这个时候 一般上游系统就会重试操作,而下游系统就需要支持幂等。
往大了说在分布式高可用设计架构中,幂等&重试 也是我们需要在架构设计中要考虑的要点,不仅仅设计中间件的应用中,所以你看知识都是相通的。

接着我们说,既然可能出现消息的重复消费,那么要么在Producer端保证消息的幂等发送,要么在Consumer端保证幂等消费。

Producer 幂等

在Kafka 0.11版本后,引入了幂等性和事务。具体就是通过在配置对象中添加如下
properties.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG,true);
Producer 自动升级成幂等性 Producer
重复数据的判断标准:具有<PID, Partition, SeqNumber>相同主键的消息提交时,Broker只会持久化一条。其中PID是Kafka每次重启都会分配一个新的;Partition 表示分区号;Sequence Number是单调自增的。
【消息队列】聊一下如何避免消息的重复消费
所以幂等性只能保证的是在单分区单会话内不重复。 说白了就是,每次重启Broker,就会失效。
但是如果我们想保证在所有分区下Producer的幂等性,就需要考虑事务型Producer。这也是幂等型Producer和事务型Producer的最大区别。

Kafka事务原理

【消息队列】聊一下如何避免消息的重复消费

事务Producer

事务型 Producer 能够保证将消息原子性地写入到多个分区中。这批消息要么全部写入成功,要么全部失败。另外,事务型 Producer 也不惧进程的重启。Producer 重启回来后,Kafka 依然保证它们发送消息的精确一次处理。
设置事务型 Producer 的方法也很简单,满足两个要求即可:

  • 和幂等性 Producer 一样,开启 enable.idempotence = true
  • 设置 Producer 端参数 transctional. id。最好为其设置一个有意义的名字。
		kafkaProducer.initTransactions(); //初始化
        kafkaProducer.beginTransaction(); //开启事务
        try {
            for (int i = 0; i < 5; i++) {
                kafkaProducer.send(new ProducerRecord<>("test1","aaa"+i));
            }
            kafkaProducer.commitTransaction(); //提交事务
        } catch (Exception e) {
            kafkaProducer.abortTransaction(); //出现异常 事务回滚
        }

幂等性 Producer 只能保证单分区、单会话上的消息幂等性;而事务能够保证跨分区、跨会话间的幂等性。
但是事务型性能比较差。

Consumer幂等

上面我们说了生产端的幂等发送,但是只在生产端保证其实不够,消费端也需要保证幂等消费。
也即:At least once + 幂等消费 = Exactly once。

  • 数据库唯一约束/redis set Nx
  • 为更新数据添加条件
  • 记录并检查操作

我们来总体说一下上面的三种方案,
第一种,一般就是在消费端消费的时候将消费数据插入到DB中,并且保证唯一约束,当消费一次后,即使同一条消息在消费一次,那么数据库层面唯一约束也会保证存在记录,不会执行后面的逻辑。或者使用redis的setNx进行保证。
第二种,在消费端消费消息的时候,可以判断一下当前的状态或者数据是否是已经处理过的状态,如果是直接丢弃,比如生产端发送的消息是初始化订单状态,但是消费端如果接受到的是处理中订单,说明已经处理过,没必要进行处理。

小结

本节主要介绍了消息重复消费,以及引出幂等性,然后分别是生产端(幂等/事务)以及消费端的幂等,但是在开篇已经说了,幂等超时重试不仅仅在消息队列中存在,在HTTP服务设计,保证表单或者APP重复提交,以及在微服务设计幂等,保证RPC自动重试也是同样适用的。文章来源地址https://www.toymoban.com/news/detail-495198.html

到了这里,关于【消息队列】聊一下如何避免消息的重复消费的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何保证消息不被重复消费?

           在Java中,可以使用消息队列来实现消息的异步处理,其中常用的消息队列有 RabbitMQ、ActiveMQ、Kafka 等。 为了避免消息被重复消费,可以使用以下几种方法: 常见的消息队列如 Kafka、RocketMQ等提供了幂等性机制,能够确保同一条消息被消费多次时只会产生一次影响。在

    2024年02月16日
    浏览(33)
  • kafka如何保证消息不被重复消费

    (1)kafka有个offset的概念,当每个消息被写进去后,都有一个offset,代表他的序号,然后consumer消费该数据之后,隔一段时间,会把自己消费过的消息的offset提交一下,代表我已经消费过了。下次我要是重启,就会继续从上次消费到的offset来继续消费。但是当我们直接kill进程

    2024年02月11日
    浏览(51)
  • 什么是mq?可靠性、重复消息、重复消费、丢失、发送大文件、延迟、发送机制、重试、死信、幂等、有序、大小、过期、优先级、进了死信队列还能出来吗?

    “MQ” 指的是消息队列(Message Queue),是一种用于异步通信的技术。消息队列是一种中间件,用于在分布式系统中传递消息,使不同组件之间能够进行松散耦合的通信。它的核心思想是生产者将消息发送到队列,而消费者从队列中接收并处理消息。 消息队列的主要优点包括

    2024年02月06日
    浏览(56)
  • RabbitMQ避免重复消费

    在Java中,可以使用消息队列来实现消息的异步处理,其中常用的消息队列有 RabbitMQ、ActiveMQ、Kafka 等。 什么是幂等性? 幂等性是指无论操作执行多少次,都是得到相同的结果,而不会产生其他副作用。 在rabbitMQ中 什么是消息重复消费? 同一条消息在MQ中被消费多次 出现重复

    2024年02月03日
    浏览(30)
  • kafka怎么避免重复消费

    首先,Kafka Broker上存储的消息都有一个Offset的标记,然后Kafka的消费者是通过Offset这个标记来维护当前已经消费的一个数据的。消费者每消费一批数据,Kafka Broker就会更新OffSet的一个值,避免重复消费的一个问题。 默认情况下,消息消费完成以后,会自动提交Offset这样一个值

    2024年04月15日
    浏览(50)
  • RocketMQ和Kafka的区别,以及如何保证消息不丢失和重复消费

    性能(单台) 语言 多语言支持客户端 优缺点 RocketMQ 十万级 java java 模型简单、接口易用,在阿里有大规模应用 文档少,支持的语言少 Kafka 百万级 服务端scala,客户端java 主流语言均支持 天生分布式、性能最好,常用于大数据领域 运维难度大,对zookeeper强依赖,多副本机制

    2024年01月16日
    浏览(48)
  • 消息队列-Kafka-消费方如何分区与分区重平衡

    消费分区 资料来源于网络 消费者订阅的入口:KafkaConsumer#subscribe 消费者消费的入口:KafkaConsumer#poll 处理流程: 对元数据重平衡处理:KafkaConsumer#updateAssignmentMetadataIfNeeded 协调器的拉取处理:onsumerCoordinator#poll 执行已完成的【消费进度】提交请求的回调函数:invokeCompletedOff

    2024年04月14日
    浏览(33)
  • Kafka如何保证消息的消费顺序【全局有序、局部有序】、Kafka如何保证消息不被重复消费、Kafka为什么这么快?【重点】、Kafka常见问题汇总【史上最全】

    目录 Kafka消息生产 一个Topic对应一个Partition 一个Topic对应多个Partition Kafka消息的顺序性保证(Producer、Consumer) 全局有序 局部有序  max.in.flight.requests.per.connection参数详解 Kafka的多副本机制 Kafka的follower从leader同步数据的流程 Kafka的follower为什么不能用于消息消费 Kafka的多分区

    2024年04月11日
    浏览(54)
  • mq常见问题:消息丢失、消息重复消费、消息保证顺序

    mq常见问题:消息丢失、消息重复消费、消息保证顺序 消息丢失问题 拿rabbitmq举例来说,出现消息丢失的场景如下图 从图中可以看到一共有以下三种可能出现消息丢失的情况: 1 生产者丢消息 生产者在将数据发送到MQ的时候,可能由于网络等原因造成消息投递失败 2MQ自身丢

    2024年02月09日
    浏览(60)
  • RabbitMQ防止消息重复消费、保证异步消息的幂等性

    一、rabbitmq出现消息重复的场景 1、消费成功,没有进行ack,这时 Broker 会重新发送 2、不确认(unack)或 reject 之后,重新排队,Broker 会重新发送 3、消费成功,ack时宕机,没有ack成功,消息由unack变为ready,Broker又重新发送 4、总的来说就是 Broker 发送消息后,消费端收到消息

    2024年02月13日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包