ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【架构师面试-消息队列-3】-消息的幂等性

2021-11-23 10:03:06  阅读:180  来源: 互联网

标签:消费 队列 重复 排重 消息 offset 架构师 丢失


1:什么是幂等性?

幂等【idempotence】是一个数学与计算机学的概念,常见于抽象代数中。在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。

ps.幂等函数,或幂等方法是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。

大白话:幂等性就是一个数据或者一个请求,给你重复来了多次,你得确保对应的数据是不会改变的,不能出错。

2:消息队列的三种消费方式

性能层层递减,可靠性逐步提升【1 -> 2 -> 3】

1. At Most once:消息至多被消费一次,消息可能会丢失,但绝不重传。

特点:吞吐量达,实现简单。消息可能会丢失

2. At lest once:消息至少被消费一次,消息可以重传,但绝不丢失。

特点:消息不会丢失,消息会出现多次投递【重复消息】

3. Excatly once:每一条消息只被传递一次

特点:消息不会丢失,消息不会重复。实现起来比较复杂,相比较下来性能不佳

3:为什么会出现重复消息呢?

正常情况下,出现重复消息的概率其实很小【程序员的第六感】

对于 Producer 来说:可能因为网络问题,Producer 重试多次发送消息,实际第一次就发送成

功,那么就会产生多条相同的消息。

对于 Consumer 来说:可能因为 Broker 的消息进度丢失,导致消息重复投递给 Consumer 。

Consumer 消费成功,但是因为 JVM 异常崩溃,导致消息的消费进度未及时同步给 Consumer 。

对于大多数消息队列,考虑到性能,消费进度是异步定时同步给 Broker

举例: kafka有一个叫做offset的概念,就是每个消息写进去,都有一个offset代表他的序号,然后consumer消费了数据之后,每隔一段时间,会把自己消费过的消息的offset提交一下,代表我已经消费过了,下次就算重启,kafka就会让消费者从上次消费到的offset来继续消费。但是万事总有例外,如果consumer消费了数据,还没来得及发送自己已经消费的消息的offset就挂了,那么重启之后就会收到重复的数据。

4:如何保证消息的幂等性?

消费者实现幂等性,有两种方式:

方式一:框架层统一封装:

消息排重唯一标识,由Producer基于消息生成唯一标识

消息排重标识的存储器:关系型数据库(排重表),KV数据库

排重逻辑:

业务逻辑执行成功:插入排重记录,并且需要让插入记录和业务逻辑在同一事务中。

业务逻辑执行失败:不能插入排重记录

方式二:业务层自己实现【建议】:

方式很多,这个和 HTTP 请求实现幂等是一样的逻辑:

乐观锁

先查询数据库,判断数据是否已经被更新过。如果是,则直接返回消费完成,否则执行消费。

更新数据库时,带上数据的状态。如果更新失败,则直接返回消费完成,否则执行消费。

分布式锁,Zookeeper 或者 Redis 实现分布式锁

 

标签:消费,队列,重复,排重,消息,offset,架构师,丢失
来源: https://blog.csdn.net/chongfa2008/article/details/121470872

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有