接口的幂等性指的是:同一个接口,多次发出同一个请求,必须保证操作只执行一次。
保证接口幂等性的方式有多种,下面列举几种常用的。
1. token机制
/--------\ /--------\ /-------\
| |-----1.获取token---->| | | |
| client |<----3.返回token-----| server |-----2.生成token,存入redis---->| redis |
| |-----4.携带token---->| | | |
\--------/ \--------/ \-------/
|
|
v
判断token是否存在? ----------不存在--------> 代表重复请求,不进行业务处理
|
存在
v
删除token,进行业务处理
2. 使用Post/Redirect/Get模式
在提交后执行页面重定向,这就是所谓的Post-Redirect-Get(PRG)模式,简单来说就是当用户提交连表单后,跳转到一个重定向的信息页面,这样就避免用户按F5刷新导致的重复提交,而且也不会出现浏览器表单重复提交的警告,也能消除按浏览器前进和后退导致同样重复提交的问题。
3.乐观锁
如果更新已有数据,可以进行加锁更新,也可以设计表结构时使用乐观锁,通过version来做乐观锁,这样既能保证执行效率,又能保证幂等, 乐观锁的version版本在更新业务数据要自增。
4. 缓冲队列
将请求都快速地接收下来后放入缓冲队列中,后续使用异步任务处理队列中的数据,过滤掉重复的请求,该解决方案优点是同步处理改成异步处理、高吞吐量,缺点则是不能及时地返回请求结果,需要后续轮询得处理结果。
除了上面这几种方式之外,还有其他方法也可以达此目的。
异步接口
接口执行异步任务保证幂等性的含义是,客户端调用接口,接口启动异步任务后返回给客户端,怎么保证异步任务正在执行过程中接口被重复调用,实际的异步任务逻辑只执行一次?
有两种方式解决:
1. 接口端过滤:这个问题关在在于重复调用,因此在接口端区分出某两次调用是否是重复调用就可以解决这个问题,因此可以通过集中式存储,保存请求记录,服务端在收到请求后,用原子性查询和保存操作,保证对于重复的请求只保存一个,这样就算是分布式场景,其他节点收到请求后也可以通过集中存储查询此次调用是否是重复调用。
2. 异步任务端校验:如果不在接口段过滤,在创建异步任务时,可以采用刚才提到的缓冲队列,过滤掉重复请求,对于分布式环境可以采用分布式缓存系统实现。