分布式系统如何保证接口幂等性解析

分布式系统如何保证接口幂等性解析

1、简介

接口幂等性,就是说一个接口,多次发起同一个请求,保证接口的结果是准确的。
比如,订单系统调用支付系统进行支付,因为网络超时原因,订单系统发起了两次支付请求,因为负载均衡算法落在了不同的机器上,造成一个订单扣款两次,就尴尬了。
保证幂等性主要是三点:

  • 对于每个请求必须有一个唯一标识。
  • 每次处理完请求之后,必须有一个记录标识这个请求处理过了。
  • 每次接受请求需要进行判断之前是否处理过。比如一个订单已经支付过了,就已经有了一条流水,如果重复发送这个请求此时插入支付流水,订单id已经存在了,唯一键约束,报错插不进去。保证接口幂等性。
    对于如何保证接口幂等性,还需要在实际工作中,结合自己的业务。

2、保证接口幂等性常见方案

  • 业务表内唯一索引
    比如你要对创建销售出库单的接口保证幂等性,即保证一个订单只能有一个对应的销售出库单。
    销售出库单表里面,可以针对销售出库单表中的订单id,创建一个unique key唯一索引,如果接口重试,两次创建同一个销售单,一定会违反唯一索引,报错。
    这种方案常见于插入,并且这个数据在数据库中只能有一条数据。

  • 业务表内状态机
    比如订单状态一般有待支付、待发货、已发货等等状态,修改订单状态只能依次按顺序,不能从待付款直接到已发货状态,比如说将订单状态修改为待发货的时候。
    update order set status = “待发货” where status = “待支付” and id = 1,订单的状态其实就变为了“待发货”。假如说id = 1的订单接口重复调用,又要执行一次这个操作的话,就不会生效了,就不会再次修改了。

  • 基于版本号的更新
    一般不常用,对于接口调用方来说,要多做一些事情,他要先查出来数据的version,调用修改接口的时候,传过去这个version。

  • 基于mysql的去重表/基于redsi的去重
    这个方案是很常见的一个方案。
    将所有的参数拼接成一个字符串,或者是从这些入参里选择一些参数,可以唯一标识这一次请求。
    如果基于mysql,单独搞一个表出来,就一个字段,建一个唯一索引,插入数据到表里去,如果这个接口被重复调用的话,再次插入一个表的话,唯一索引会报一个冲突出来,这次插入就会失败。
    这个方案还是不错的,尤其是并发不是特别高的话,接口被调用的并发不是特别高的话,每秒的并发请求量在1000左右,1000以内的话,用mysql的去重表也没什么问题。
    但是如果接口调用量很大,并发很高,一秒请求量达到了几十万,选择使用redis,拼接一个串出来,直接set设置到redis里去,如果下一次人家请求再过来了,此时会发现这个key已经存在了,那么这个时候就不能执行了,因为已经出现重复调用了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值