当前位置: 首页 > Web前端 > HTML

幂等设计详解

时间:2023-03-28 14:04:42 HTML

简介本文主要从研发人员的角度分析幂等处理的时序,结合研发人员在日常生活中经常使用的各种常见业务场景,从经典系统框架的每一层入手.希望通过本文的分析,让开发者在日常开发中不再对幂等处理感到陌生。抓住导致请求和接口不幂等的本质,避免在工作中落入这个陷阱。idempotent和idempotent这两个词对于研究人员来说再熟悉不过了。你有没有深入思考过幂等性的背景,为什么需要幂等性,如何做到幂等性?今天我们就结合业务场景和请求流程来分析一下幂等性(property)的解决方案。1概念幂等性的概念是一个数学概念,即:f...(f(f(x)))=f(x)。用在计算机领域,是指系统中某个接口或方法的对外承诺。在同一资源上以相同的参数重复调用接口或方法与调用一次的结果是一样的。2业务场景从业务场景来看,例如:在目前的互联网电商订单服务中,如果同一用户在短时间内调用某个订单服务,则只能成功下单一次;银行账户之间转账,A账户向B账户转账,无论系统出现什么问题或故障,转账只能成功一次;前端页面针对同一个表单内容向后端发起多次提交请求,后端只能给出一个相同的结果等等等类。试想,如果提供的这些服务不是幂等的,当客户因网络不稳定下单或连续多次点击下单按钮时,实际客户只下了一个订单,结果系统生成了多个订单为客户。平台/商家将难以承受。如果被“羊毛党”盯上,损失将不可估量;在银行之间的转账中,A账户实际上只转了一百万给B账户,B账户却收到了上百万,这在商业上是不可接受的。开发者分析这些业务场景,发现不管是订单服务,转账服务,还是表单提交都是业务请求,提供这些业务服务的接口或者方法应该保证无论服务是否异常,比如超时,retry,orfault,无论如何,必须满足业务处理结果是正确的。对于一个或多个业务请求,最终的处理结果是一致的,即在一定时间内,服务的幂等性实际上就是请求的幂等性。3架构分析分析系统架构,幂等应该在哪一层做,应该怎么做?图1经典系统框架图上图是最常见的经典系统框架图。Web端向后端发起请求。幂等性应该在哪一层处理?不妨逐层分析。Nginx需要幂等吗?Nginx的主要功能是作为web服务器、反向代理、负载均衡器等,将请求转发给后端服务器。它不参与具体的服务,所以Nginx不需要幂等。;网关负责权限验证、安全防御、认证鉴权、流量控制、协议转换、日志审计、监控等,不包含任何业务处理,因此不需要做幂等处理;Service层通常是处理和安排业务逻辑,可能会改变数据,但是数据改变的结果最终还是需要通过数据访问层写入数据库,所以Service层不需要数据幂等;DAO层主要是与数据库交互,将Service层的结果写入数据库,为Service层提供读写数据库的功能。写入数据库时??,每次写入可能会返回不同的结果。这时候就需要根据场景进行具体分析;DataBase层主要提供数据存储,不参与具体的业务逻辑计算。因此,通过对架构各层的功能分析,得出请求的幂等处理需要在DAO层进行处理,以保证多次请求和一次请求的结果一致。4数据库操作分析通过以上分析,得出幂等性需要在DAO层进行处理,进一步分析可知DAO层的操作主要是CRUD。接下来分析每个操作是否需要幂等性,以及如何做。R(read):对应的操作SQL语句是select。只要查询条件不变,在一定时间内,执行一次和执行多次返回的结果一定是一样的,所以是幂等的,不需要处理。从id=1的用户中选择*;查询一次或多次的结果都是一致的,所以是幂等的。C(create):对应的操作SQL语句是insert。这个时候就需要分情况。如果使用的数据库主键是数据库自增,无论业务主键防重的情况下,每次写入数据库都不是幂等的。因此,为了保证幂等性,需要在插入数据之前插入数据。在数据库表上做业务防重或者对业务主键加唯一索引。如果数据库主键不是自增的,是业务系统写的,需要在业务系统中做数据库主键和业务主键的一对一映射,或者独立的服务提供数据库主键与业务主键的映射关系,保证多次请求得到的数据库主键与业务主键一致,保证写数据库的操作是幂等的。一般来说,同一份数据多次写入数据库后,是否能保证只有一份数据。插入用户(id,age,sex,ts)values(1,10,‘male’,2021-07-2010:22:23);U(update):对应的操作SQL语句为update。更新的时候一定要用绝对值,不能用相对值。相对值更新可能导致更新操作不是幂等的。幂等:更新用户集age=10whereid=1;非幂等:更新用户集age++whereid=1;D(删除):对应的操作SQL语句为删除。删除范围时,最好在生产中禁止此类操作;推荐的方法是先将按范围删除操作转换为按范围查询,再按查询的主键删除。并且按范围删除不是幂等的。幂等:从id=1的用户删除;非幂等:这种类型的操作是被禁止的。deletefromuserwhereidin(selectidfromuserorderbyiddesclimit10);5常见的业务场景中实现幂等的方式有很多种。下面是一些常见的业务场景。在实际应用中,根据业务场景进行选择。图2页面token机制处理流程前端页面提交时,页面token机制。进入页面时,从服务器获取token,将token存储在服务器端,提交时带上token到服务器端验证;常见的处理流程如下:乐观锁机制,利用数据库的版本号实现乐观锁,当数据库更新时,判断版本号是否与查询一致,一致则更新成功,否则更新失败;select+insert,写入数据前,先检查数据是否存在,存在则直接返回,不存在则写入数据,保证写入数据库的数据正确性;常用于一些并发度较低的后台系统或防止重复执行任务;悲观锁机制,一般id为主键或唯一索引,只锁当前记录;select*fromtablewhereid='1234'forupdate;对于去重表,每次写入或更新业务表时,先检查去重表是否已经有记录,再对业务表进行操作。数据库唯一索引为业务表创建唯一索引,避免业务数据的多次写入;状态机,业务状态在改变之前是有条件的,必须根据设定的状态条件进行更新;在实际开发中,所提供的接口或服务的幂等性(property)是最基本的技术要求。希望本文的分析能对还不了解幂等性(property)的开发者有所帮助。