0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

分析解决幂等(性)的方法

OSC开源社区 来源:京东技术 作者:京东物流-廖宗雄 2022-10-14 10:08 次阅读

本文主要从研发人员的角度,结合研发人员日常常见的各类业务场景,从经典系统框架的每一层入手分析幂等处理的时机。希望通过这篇文章的分析,让开发者在日常开发中对幂等的处理不再陌生。抓住导致请求、接口不幂等的本质,在工作中避免再陷入这个陷阱中。

幂等、幂等性这词,作为一个研发人员是再熟悉不过的,那是否有深入思考过幂等产生的背景、为什么需要幂等,如何做才是幂等的?今天将结合业务场景及请求的过程来分析解决幂等(性)的方法。

01 概念

幂等这个概念,是一个数学上的概念,即:f……(f(f(x))) = f(x)。用在计算机领域,指的是系统里的接口或方法对外的一种承诺,使用相同参数对同一资源重复调用某个接口或方法的结果与调用一次的结果相同。

02 业务场景

从业务场景上来说,如:现在互联网电商的下单服务,同一个用户在短时间内调用某一个下单服务,只能下单成功一次;银行账户之间的转账,A账户给B账户转账,无论系统出现什么问题或故障,也只能转账成功一次;前端页面对相同表单的内容多次向后端发起提交请求,后端只能给出一个相同的结果等都属于幂等的范畴。

试想一下,如果提供的这些服务不是幂等的,客户在下单时由于网络不稳定或是连续点了几次下单按钮,实际客户只下了一单,结果系统里给客户生成了多单,那平台/商家将是无法承受的,如果被“羊毛党”盯上,损失是无可估量的;银行之间的转账,A账户本来实际给B账户只转了一百万,结果B账户收到了几百万,这在业务上是不可接受的。分析这些业务场景,开发者发现,无论是下单服务、转账服务还是表单提交都是一个个业务请求,提供这些业务服务的接口或方法都应该保证无论服务是超时、重试或有故障等异常情况,都要满足业务上的处理结果是正确的。业务上的一次或多次请求,最终的处理结果是一致的,即:在一定时间内,服务的幂等其实就是请求的幂等。

03 架构分析

从系统架构上进行分析,幂等该在哪一层去做,怎么做?

59ab2bcc-4af6-11ed-a3b6-dac502259ad0.png

图1 经典系统框架图

上图为一个最常见的经典系统框架图,Web端发起一个请求到后端,幂等该在哪一层来处理呢?不妨一层一层的分析。

Nginx是否需要做幂等,Nginx的主要功能是做Web服务器、反向代理、负载均衡等,把请求转发到后端的服务器上,本身不参与具体的业务,所以Nginx是不需要做幂等处理的;Gateway是负责权限校验、安全防御、认证鉴权、流量控制、协议转换、日志审计、监控等,本身也不含对任何业务的处理,所以其也不需要做幂等处理;Service层通常是对业务逻辑进行处理、编排,可能会改变数据,但对于数据的改变结果,最终也还是需要通过数据访问层,写入到数据库,所以Service层也不需要做数据幂等;DAO层主要是和数据库交互,把Service层的结果写入数据库,对Service层提供读取、写入数据库的功能。

在写入数据库的时候,针对每一次的写入,可能返回不同的结果,此时就需要按场景进行具体的分析对待;DataBase层,主要提供数据的存储,并不参与具体的业务逻辑计算。所以,通过对该架构的每一层的功能分析,得出对于请求的幂等处理,需要在DAO层做处理,以便保证多次请求和一次请求的结果是一致的。

04 数据库操作分析

通过上面的分析,得出幂等需要在DAO层来处理,再进一步分析,得出DAO层的操作主要就是CRUD。下面逐一对每一种操作分析是否需要做幂等,以及怎么做。

R(read):对应的操作SQL语句为select。只要查询条件不变,在一定的时间内,执行一次和执行多次返回的结果肯定是相同的,所以其本身是幂等的,不需要再做处理。

select * from user where id = 1;
查询一次或多次结果是一致的,所以是幂等的。

C(create):对应的操作SQL语句为insert。此时,需要分情况,如果用到的数据库主键为数据库自增,不考虑业务主键防重的情况下,每一次写入数据库就不是幂等的,所以为了保证幂等,需要在数据insert前做业务防重或是在数据库表上对业务主键加唯一索引

如果数据库主键不是自增,是由业务系统写入的,需要在业务系统里把数据库主键和业务主键做一对一映射,或是由独立服务提供数据库主键和业务主键的映射关系,保证多次请求获取到的数据库主键和业务主键是一致的,确保写入数据库操作是幂等的。综合来说,就是相同的数据多次写入数据库后,能否保证只有一条数据。

insert into user (id,age,sex,ts) values(1,10,‘male’,2021-07-20 10:22:23);

U(update):对应的操作SQL语句为update。更新操作时,一定是要用绝对值进行更新操作,而不要用相对值进行更新,相对值更新可能导致更新操作不幂等。

幂等:

update user set age = 10 where id = 1;

非幂等:

update user set age++ where id = 1;

D(delete):对应的操作SQL语句为delete。删除操作时,如果删除的是一个范围,生产上最好是禁止该类操作;比较推荐的做法是把按范围操作删除转换为先按范围查询,再按查询的主键进行删除。而且按范围删除的操作不是幂等的。

幂等:

delete from user where id = 1;

非幂等:该类操作要禁止。

deletefromuserwhereidin(selectidfromuserorderbyiddesclimit10);

05 常见业务场景

保证幂等的实现方式有多种,此处例举几类常见的业务场景,在实际应用中,根据业务场景进行选用。

1. 前端页面提交时,页面token机制。

进入页面时,从服务器获取token,在服务器端把token进行存储,提交时把token带到服务器端进行验证;常见的处理流程如下:

59c59c00-4af6-11ed-a3b6-dac502259ad0.png


图2 页面token机制处理流程

乐观锁机制,使用数据库的版本号实现乐观锁,数据库更新时,判断版本号是否与查询时保持一致,一致更新成功,否则更新失败;

select+insert,数据写入前,先查询数据是否存在,存在直接返回,不存在则写入数据,保证写入数据库的数据正确性;常用于并发不高的一些后台系统或是防止任务的重复执行;

悲观锁机制,一般id为主键或唯一索引,仅锁定当前记录;

select*fromtablewhere id='1234'forupdate;

去重表,每一次写入或更新业务表时,先查询去重表是否已经存在记录,再操作业务表。

数据库唯一索引,为业务表建立唯一索引,避免业务数据多次写入;

状态机,业务状态在变更之前是有条件的,必须按设定的状态条件进行更新;

在实际开发中,保证提供的接口或服务的幂等(性),是一个最基本的技术要求,希望通过该分析,能对还未理解幂等(性)的研发人员有所帮助。





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • SQL
    SQL
    +关注

    关注

    1

    文章

    742

    浏览量

    43655
  • 数据库
    +关注

    关注

    7

    文章

    3649

    浏览量

    63758
  • Web服务器
    +关注

    关注

    0

    文章

    137

    浏览量

    24271
  • 状态机
    +关注

    关注

    2

    文章

    487

    浏览量

    27282

原文标题:幂等设计详解

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    基于信号完整分析的高速数字PCB的设计方法

      本文介绍了一种基于信号完整计算机分析的高速数字信号PCB板的设计方法。在这种设计方法中,首先将对所有的高速数字信号建立起PCB板级的信号传输模型,然后通过对信号完整
    发表于 06-14 09:14

    稳态热晕非晕效应的数值分析

    【作者】:孙运强;许晓军;习锋杰;陆启生;吴武明;郭少锋;【来源】:《强激光与粒子束》2010年02期【摘要】:运用高斯光束展开的方法,分析圆对称平顶光束在大气传输中的热晕及其非晕效应。通过对热晕
    发表于 04-22 11:37

    电磁兼容分析方法

    电磁兼容要求给出最佳工程设计的方法。系统法从设计开始就预测和分析电磁兼,并在系统设计、制造、组装和试验过程中不断对其电磁兼容性能进行预测和分析,由于系统中相互关系很多,因此用系统法进
    发表于 08-25 08:45

    离线计算中的和DataWorks中的相关事项

    考虑到,导致对应的单据有两条确认记录。点此查看原文:http://click.aliyun.com/m/42758/概念这个词在软
    发表于 02-27 13:24

    一种在分布式环境下实现迭代聚类的方法

    为解决迭代聚类算法并行实现中存在的编程繁琐、效率低下等问题,基于Spark大规模数据通用计算引擎及其GraphX组件,提出了一种在分布式环境下实现迭代聚类的方法。首先,利用某种相似
    发表于 12-11 15:29 0次下载
    一种在分布式环境下实现<b class='flag-5'>幂</b>迭代聚类的<b class='flag-5'>方法</b>

    基于迭代的电力系统模态谐振快速求解方法

    在谐波谐振分析方法中,模态分析方法可以揭示谐振频率、谐振幅度、谐振关键节点或位置信息,得到了较快的推广和应用,但其计算效率尚有待提高。根据
    发表于 01-03 11:43 0次下载

    在高并发下怎么保证接口的

    前言 接口性问题,对于开发人员来说,是一个跟语言无关的公共问题。本文分享了一些解决这类问题非常实用的办法,绝大部分内容我在项目中实践过的,给有需要的小伙伴一个参考。 不知道你有没有遇到过这些场景
    的头像 发表于 05-14 10:23 1650次阅读
    在高并发下怎么保证接口的<b class='flag-5'>幂</b><b class='flag-5'>等</b><b class='flag-5'>性</b>?

    电子产品可靠设计及分析方法综述

    电子产品可靠设计及分析方法综述
    发表于 07-31 16:11 24次下载

    什么是?关于接口的解决方案

    这里的乐观锁指的是用乐观锁的原理去实现,为数据字段增加一个version字段,当数据需要更新时,先去数据库里获取此时的version版本号
    发表于 10-09 10:19 1727次阅读

    Spring Boot实现接口的4种方案

    是一个数学与计算机学概念,在数学中某一元运算为时,其作用在任一元素两次后会和其作用一次的结果相同。
    的头像 发表于 11-08 10:21 816次阅读

    什么是的实现原理

    在编程中一个操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。函数,或
    发表于 01-05 10:40 5029次阅读

    一个注解,优雅的实现接口

    除了查询和删除之外,还有更新操作,同样的更新操作在大多数场景下也是天然的,其例外是也会存在ABA的问题,更重要的是,比如执行update table set a = a + 1 where v = 1这样的更新就非等了。
    的头像 发表于 08-26 14:36 461次阅读
    一个注解,优雅的实现接口<b class='flag-5'>幂</b><b class='flag-5'>等</b><b class='flag-5'>性</b>!

    基于接口解决方案

    接口是指无论调用接口的次数是一次还是多次,对于同一资源的操作都只会产生一次结果。换句话说,多次重复调用相同的接口请求应该具有与单次请求相同的效果,不会导致不一致或副作用的发生。 今天我们
    的头像 发表于 09-30 16:27 300次阅读
    基于接口<b class='flag-5'>幂</b><b class='flag-5'>等</b><b class='flag-5'>性</b>解决方案

    和非请求的一些定义和分析

    , HEAD, OPTIONS, PUT or DELETE). ” 什么意思呢?默认情况下,只有当出现网络问题,是“请求”的 5xx 状态码的情况下,才会发起重试,而这里面并不包含 POST 请求。 我就好奇了,这
    的头像 发表于 10-17 10:50 464次阅读

    探索LabVIEW编程接口原理与实践

    原来是数学上的概念,在编程领域可以理解为:多次请求某一个资源或执行某一个操作时应该具有唯一同样结果,也就是说,其任意多次执行对资源
    的头像 发表于 02-29 10:24 342次阅读
    探索LabVIEW编程接口<b class='flag-5'>幂</b><b class='flag-5'>等</b><b class='flag-5'>性</b>原理与实践