【全网最通俗】什么是幂等性

温馨提示:本文无配图,纯文字。

一、引言

之前没有接触过分布式,redis是什么,消息队列(Message Queue)里的Kafka是什么,一改不知,听这些东西感觉好高级,菜鸡的我在屏幕前瑟瑟发抖。看别人的面试视频问“有没有用过kafka?”“kafka里面怎么保证幂等性?”,卧槽,听到这里带来了满满的焦虑,什么又是幂等性?还要用数学里面的次幂来实现什么超复杂算法吗?想到这里又不由得产生了畏难心理。这不,最近心态比较好,上网搜了个幂等性的相关概念。就有了下面的内容

二、先摆结论

幂等性,就是套个个高大上名字的普通概念,根本就不是新概念,甚至你开发时还经常会实现所谓的幂等性。

1、再详细点

幂等性的通俗概念:

调用方,对一个系统进行重复调用(参数全部相同),不论重复调用多少次,这些调用对系统的影响都是相同的效果。就是不论调用我多少次你对我的影响以及你的影响都是不变的,不会随着次数的变化而改变。

举个简单的例子:

天然幂等性:

假设对象Person中有个name属性,有个

setName(String name){
   this.name = name
}

的方法,那这个方法就是天然幂等的哦,你输入相同的“小明”参数,不论你重复调用多少次都是将名字设置为“小明”,其对对象Person的影响都是一样的。这就是天然幂等性。

非幂等性:

还是拿对象Person举例子,假设对象中有个age属性,有个

increaseAge(){
   this.age++;
}

方法,我们按正常的步骤一次一次调用是不会有问题的,如果调用者没有控制好逻辑,一次流程重复调用好几次,这时候影响效果和一次是有非常大区别,代码编写者以为它只会调用一次,结果出现了意外调用了很多次,恰好方法不具有幂等性,于是就会出现和预期不一样的效果。这个方法本身是不具备幂等性的,我们可以修改这个方法,让其传入一个标识符,每一次重复的请求会有相同的标识符,方法内部可以根据标识符查数据库是不是已经处理过,如果处理过就不重复处理。这样方法就具备了幂等性。

再举个实际点的例子:

客户在进行一笔转账交易,后端划分了两个系统来处理这个转账的流程:
①系统A负责收集转账人和接收人还有金额的信息然后传给系统B进行转账,将控制逻辑留在系统A。
②系统B读取系统A传过来的信息,负责更改数据库的金额。如果操作成功,就回复系统A成功,如果失败就回复系统A失败。
③系统A可以接受系统B操作成功或失败的回复,但是我们知道,系统A这个交易流程是有等待时间的,如果等待超时,它不确认是否是转账成功或失败,于是系统A会重试调用直到得到一个明确的回复。

这是系统大致的交易流程。这个流程是有问题的,系统B提供的操作接口不是幂等性的。

逻辑漏洞:

假设系统B操作成功了,但是由于系统B回复的时候遇到网络抖动、网络阻塞、网络风暴等,这个成功的消息没有及时被系统A接收,系统A再重试让系统B转账,结果会导致:用户点击一次转账,后台为他转了很多笔。这是非常危险的。

解决办法:

我们可以为每一笔用户发起的转账请求赋予一个全局唯一的ID,把这个ID在调用系统B的时候一起传输进去,第一次系统B处理的时候正常处理,处理完之后把转账成功还是失败的状态与ID一起存入数据库,下次重复请求会查找数据库,查出来数据为空则代表第一次请求,查出来状态为成功,则直接返回成功,查出来状态为失败,则再操作一次。这样能确保不会出现上述逻辑错误

三、总结:

很多方法具有天然的幂等性,有的方法不具备,我们需要业务逻辑层来实现幂等性。我们开发的过程中考虑全面了就能自然的实现幂等性,幂等性根本就不是什么新的知识。

  • 20
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr. 良爷

您每一分的打赏都是对原创的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值