幂等简单的定义:redis
系统中的屡次操做,无论多少次,都应该产生同样的效果,或返回同样的效果。数据库
好比实际的业务请求为建立一个活动,理论上须要根据业务形态开发幂等建立活动的接口,这样在相同参数调用接口屡次建立活动时,只能够建立成功一次。安全
因为查询天生的是幂等请求,因此针对于查询场景能够不作业务角度的幂等约束,查询幂等的约束可能是针对于资源控制,安全防刷,流控来作的。分布式
试想有这样一个场景:
A系统传递userId和活动Id调用B系统发券,若是B系统发券成功,须要返回A系统本次发券userId和发券code。
因为B系统须要对本身发出去的券进行限制防止超发,因此会根据userId和code创建幂等拦截。
可是A系统的调用次数是不受信的,B系统会对屡次重复的请求作拦截,这样形成一部分A的请求为无效请求,被直接打回。
可是A系统接受B系统的返回值中是须要code的,若是没有收到code,A系统会认为调用B系统失败,进行重试,结果就形成了A系统不停被重试,B系统拦截无效请求,返回默认值,A再重试的死循环。优化
解决这个场景问题有两种方法:设计
第一种方案明显的缺点在于,针对于重复发送的请求都会转化成一次查询操做,这样无形中加大了对于B系统资源的浪费,同时因为发券接口逻辑中引入了查询逻辑,形成此接口违反了“单一职能原则”,在将来围绕这个接口的新业务逻辑形成的代码修改时,好比容许对同一个用户发送多张券,可能出现潜在的bug问题。code
第二种方案则是我选择的更好的方案,也是更支持的方案,一个接口最好只作一件事,这样一个接口只作发券,同时对于屡次重复发券作请求拦截,没有必要放无效请求到系统核心逻辑中,更没有必要所以引入查询逻辑消耗系统资源。
在调用B系统发券接口由于拦截重复请求,返回重复请求状态码后,系统A调用B系统的查询接口,进行已发送code的查询,这样在使用角度和后期业务迭代角度及系统资源使用和将来优化角度来讲,都存在必定的空间,而不会形成代码复杂度提高引入隐患bug。索引
针对于幂等操做还有以下几种方案:token