当前位置:   article > 正文

分布式开发(二)---接口幂等性(防止重复提交)_同一个接口,多次发出同一个请求,必须保证操作只执行一次。 也就是指用户对于同一

同一个接口,多次发出同一个请求,必须保证操作只执行一次。 也就是指用户对于同一

说明下:这里说的接口主要指非查询类接口,因为查询类接口天然具备幂等性

一、背景

交易系统里用户下单提交订单时,由于用户连续快速点击,导致连续发送多次请求,分别命中到了不同的服务器, 那么就会生成多个内容完全相同的订单,只有订单号不同而已。


当然造成重复请求的原因,还有其他的可能:

  1.  网络波动,引起重复请求
  2. MQ重复消费
  3. Nginx重试
  4. 黑客拦截请求后重发
  5.  ......

重复请求的影响

  • 下单时,用户面对多个一模一样的订单,不知道应该支付哪个。
  • 这些重复数据,对系统来说也是脏数据,还会影响正常的校验。
  • 下单成功如果发送短信提醒用户,但发送了几个内容一样的短信。

所以接口支持幂等性非常重要,尤其是涉及交易的接口。

二、什么是幂等性?

所谓幂等性, 通俗点说就是一个接口, 无论执行几次所产生的影响与只执行一次产生的影响是一样的

举例子说明下:
• 支付接口, 重复支付同一笔订单,最终也只能成功扣款一次。
• 支付宝、微信支付成功回调接口, 可能会多次回调, 必须只能成功处理一次。
• 普通表单提交接口, 多次点击提交, 数据只能成功落地一次。


三、常见解决方案

1. 唯一索引: 防止新增脏数据,保证最终插入数据库的数据只有一条。
2. token机制: 防止页面重复提交。
3. 悲观锁 -- 获取数据的时候加锁(一般是行锁)。
4. 乐观锁 -- 基于版本号version实现, 在更新数据那一刻校验数据。
5. 分布式锁 -- 通过第三方的系统(redis或zookeeper),在业务系统插入或更新数据时,获取分布式锁,然后做操作,最后释放锁。

四、分布式锁实现方案详解

解决思路:同一用户在1秒内对同一URL的操作视为重复提交
具体步骤:

  1. 服务器A接收到请求之后,尝试获取锁,获取成功 。
  2. 服务器A进行业务处理,订单提交成功。
  3. 服务器B接收到相同的请求,尝试获取锁,失败。因为锁被服务器A获取了,并且未释放。B 获取锁失败之后,直接返回。
  4. 服务器A处理完成,释放锁。

代码实现

  1. @PostMapping(value = "/submit-order")
  2. public Response<Boolean> submitOrder(HttpServletRequest request, OrderParam,orderParam){
  3.         
  4.         String userId= "123456";//用户
  5.         String path = request.getServletPath();
  6.         String key = MD5(userId+path);
  7.         
  8.         //1. 获取redis锁
  9.         String result = jedis.set(key, orderParam, "NX", "EX", 1000);
  10.         boolean success = "OK".equals(result);
  11.         try {
  12.             if (success) {
  13.                 //2. 执行具体业务逻辑
  14.                 //...
  15.             }else{
  16.                 //3. 获取锁失败
  17.             }
  18.         } catch (Exception e) {
  19.             e.printStackTrace();
  20.         } finally {
  21.             //4. 业务逻辑执行完成之后,释放锁
  22.             jedis.del(key);
  23.         }
  24.         
  25.         return ResponseUtil.success(Boolean.TRUE);
  26.     }

总结

其实思路很简单, 我们也可以通过拦截器(AOP)+注解的方式实现一个通用的解决方案, 就不用每次请求都写重复代码。
幂等性在设计系统时,是需要首要考虑的问题,尤其是在像银行,支付宝等互联网金融公司等涉及到钱的系统。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/234709?site
推荐阅读
相关标签
  

闽ICP备14008679号