分布式系统,这样保证幂等性,很简单嘛

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

前言

今天和大家分享一些关于分布式中幂等性的知识点,这属于分布式中的基础和重点,学习完本文可以学习以下知识:

  • 幂等性是什么
  • 为什么要保证幂等性
  • 如何保证幂等性

幂等性是什么?

举一个具体的例子,比如在秒杀系统中的,对一个秒杀商品,多次发起下单按钮,对于下单接口来说,该接口必须保证订单记录只能插入一条,库存只能扣减一次,这就是幂等性。

为什么保证幂等性?

对于单机部署的系统来说,我们可以通过在内存中添加一个map,当接收到一个客户端请求后,在map中增加一条该记录的key,当下次该id又再次请求时,就去map中进行查询,如果查询到key已经存在,就直接返回。

对于分布式来说,因为系统分别部署在不同的机器上,无法使用上述方式来解决,但是这个问题又必须考虑,否则后续会导致很多的问题,比如遇到网络波动,前端没有做防抖等都会造成接口被重复请求的情况存在。

image.png

比如上述部署了3台机器,每台机器部署一个系统A的实例,当用户在客户端发起一次请求时,因为网络阻塞,虽然后台已经接收到请求,但是前端返回请求失败,此时用户再次发起提交请求,这就导致多了一次提交请求,如果不加以控制,会生成多条订单信息。

之前花哥也是遇到一个可能出现幂等性的场景,对结果微信支付的小伙伴应该了解,当我们调用微信统一支付,并完成支付时,微信平台会进行回调,这时会有一种情况,如果我们收到微信回调,但是没有返回成功给微信端,微信平台会继续回到业务平台,此时我们就要保证接口的幂等性。

如何保证幂等性?

分布式系统中,可以通过下面三个方式来保证幂等性:

  1. 在每个请求上添加唯一标识,比如订单支付时,增加一个订单id,同一个订单id只能处理一次;
  2. 在数据库中添加记录,比如微信回调后,修改订单状态,或者增加记录流水号,这样微信每次回调时,接口先进行查库判断,如果已经存在记录,就直接返回;
  1. 增加一个redis中间件,其实这个类似单机系统中的map,我们每次处理完一个请求后,将该请求的唯一id记录在redis中,下次该请求再来请求时,因为redis已经存在该记录的key,就不再处理。

写在最后

今天和大家分享了一些常见的保证分布式幂等性的解决方案,当然还有很多种其他方式,根据具体的业务场景选择合适的方案。