什么是幂等?
编程中一个幂等指的是:
任意多次执行对资源产生的影响均与一次执行的影响相同。
注意哦,只要有一次执行(请求)产生了影响之后的执行均不会再产生影响。所以,幂等关注的是以后的多次执行(请求)是否对资源产生的影响,而不关注结果。
幂等服务,是为了防止请求方无论因为什么原因进行多次请求而对资源产生不同影响存在的,和请求的返回值没有任何关系。如果想做的精细点,可以让第一次产生影响的返回值返回成功,之后的都返回请求重复等,但这其实和幂等没什么关系,只是防重的一种用户体验罢了
咋一看有同学会问了,这和测试有什么关系?其实有很大关系,测试过消息服务和支付系统的小伙伴应该很有发言权。
-
消息服务
用户在接收到两条或多条一样的推送消息时会不会很奇怪?如果运营在后台进行发送推送的操作,后台由于重试等原因触发了两次相同的请求,那相关的用户自然就会收到两次推送。但是如果服务幂等就可以解决这个问题。 -
支付系统
用户在进行一笔扣款结果被多扣了会不会很愤怒?用户买东西触发了一笔扣款,客户端由于重试触发了又一次请求,会不会扣了两笔一样的钱?同样的,如果服务幂等也解决这个问题。
有同学会问了,这说了半天,不就是重复提交的问题吗?那解决了重复提交,不就不用这么麻烦了么?
面对这个问题,我只能说你说得对!但是成本呢?可以试想一下,是解决客户端的重复提交问题简单,还是服务端加幂等简单?客户端产生重复提交的情况很多,网络不稳定这个事儿就已经很玄学了,再加上客户端有甚多,还分不同的系统,咋解决?所以,服务端来做成本最低,但是相对的,服务端的业务复杂度必然的增加了,而且降低了服务的性能。究其原因,就要看幂等的实现了。
幂等的实现
简单来说,幂等的实现就是:业务单号(加校验)+ 锁(防并发问题,查询和变更状态操作加锁)
1. 业务单号(增加了服务业务复杂度)
幂等需要通过唯一的业务单号来保证,也就是说相同的业务单号,认为是同一笔业务。使用这个唯一的业务单号来确保,后面多次的相同的业务单号的处理逻辑和执行效果是一致的。试想一下,在支付时,我会先查询一个业务单号是否被支付过,然后再去进行是否支付的处理,这样不就OK了?这个业务单号也不用想的太复杂,它可以是一个时间戳和用户id的组合,也可以是一个主键id,只要能保证不重复且有明确的对应关系,都可以。
2. 锁(降低了服务性能)
锁是为了防止高并发问题的。刚才说了,在扣款时,我会先查询一个业务单号是否被扣除过,然后再去进行是否扣款的行为。但是,在高并发情况下,同时会发起很多查询及变更,就有可能产生并发问题,在我还在进行扣款行为的过程中进行了查询,就又会发起一笔扣款,导致多扣。这个时候,我们就要加锁了,将并行改为串行。
锁的话可以采用乐观锁、防重表、分布式锁、token令牌等,这个不是本次需要讨论的范畴,就不多说了。
测试人需关注
对于测试来说,很多时候我们是要考虑多次请求是否会对资源的影响不同的,这个要时刻和业务绑定,需要我们这些对需求有天然敏锐嗅觉的人来发现。将幂等作为之后接口测试中检查的一步,会帮我们提前发现不少问题
网友评论