高并发保证接口幂等性方案

接口幂等的解决方案

什么是接口幂等性

接口幂等性是指无论调用多少次相同的接口请求,对系统的状态和数据产生的影响都是一致的。简而言之,幂等性保证了对同一个接口请求的重复调用不会产生额外的副作用或改变系统的状态。

在设计和实现接口时,考虑接口的幂等性非常重要。下面是一些常见的幂等性要求:

  1. 相同的请求重复调用不会产生不一致的结果:对于相同的请求,无论调用多少次,返回的结果应该是一致的。例如,查询接口应该返回相同的结果,不管调用多少次。

  2. 幂等操作不会重复执行:对于具有副作用的操作,例如创建、更新或删除操作,重复调用同一个请求不会导致多次执行操作。例如,多次创建同一个资源只会创建一次,并且返回相同的资源标识符。

  3. 并发调用不会产生冲突:即使多个请求同时调用同一个接口,也不会导致数据冲突或不一致的状态。例如,在并发情况下,多个请求同时对同一资源进行更新操作,最终的结果应该是一致的。

什么情况会发生幂等性问题

在实现接口的幂等性时,可能会遇到以下一些常见的问题:

  1. 并发操作:并发操作是最常见的幂等性问题之一。当多个请求同时访问同一个接口,并且对共享资源进行修改时,可能会导致数据冲突或不一致的状态。在并发操作中,需要采取适当的并发控制措施,如乐观锁、悲观锁或事务控制,以确保操作的原子性和一致性。

  2. 请求重试:由于网络问题或其他原因,客户端可能会重试发送请求,导致同一个请求被多次执行。在这种情况下,需要保证重复的请求对系统的状态没有额外的副作用。可以通过在服务端对请求进行幂等性校验,或者在客户端使用唯一的请求标识符来处理请求重试的问题。

  3. 非幂等性操作:某些操作本身就是非幂等的,即每次执行都会产生不同的结果或副作用。例如,生成唯一标识符、发送短信或电子邮件等操作。在设计这类操作时,需要明确其非幂等性,并根据具体业务需求进行处理,如限制操作的频率、采用幂等键等方式来保证操作的一致性。

  4. 服务故障和恢复:当服务发生故障或崩溃后重新启动时,可能会导致幂等性问题。例如,如果服务在崩溃前已经处理了某些请求,但在恢复后无法恢复处理状态,可能导致重复处理之前已经处理过的请求。为了解决这个问题,可以使用持久化存储来记录已处理请求的状态,或者通过使用消息队列等机制来确保请求的可靠传递和处理。

  5. 缓存失效:如果接口的幂等性依赖于缓存,当缓存失效或被清除时,可能会导致幂等性问题。在这种情况下,需要在缓存失效后,能够重新生成或恢复缓存数据,并保证请求的幂等性。

  6. 数据库约束:如果数据库中缺乏适当的约束或唯一性约束,可能会导致数据的重复插入或更新,从而违反了幂等性。在设计数据库结构时,应该考虑合适的约束和索引,以确保数据的唯一性和一致性。

这些是一些常见的幂等性问题,实现幂等性需要根据具体业务场景和需求进行分析和解决。通过合理的设计和实施,可以有效地处理这些问题,确保接口的幂等性和系统的一致性。

解决方案

本文就不对数据库唯一主键加悲观锁乐观锁等方案进行分析了,因为一般的业务场景都无法使用这些简单的方案。

  • token令牌

    token令牌的方案,把一个请求分为两个步骤,第一次请求获取token;第二次请求带着这个token完成业务操作。

    • 第一步,先获取token。

高并发保证接口幂等性方案_第1张图片

  • 第二部,使用token完成业务。
    高并发保证接口幂等性方案_第2张图片

    在 Redis 中,当你尝试删除一个键(key),如果该键不存在,删除操作将会默默地失败,并且不会出现任何错误或异常。这意味着如果你执行删除操作的键不存在,Redis 将会返回 0,表示没有键被删除。

  • 分布式锁

    分布式锁就比较简单和粗暴了,我们可以使用redisson框架来配合使用,用到的比较多的是联锁和可重入锁。

    分布式锁需要注意的地方:

    • 锁的命名:我们在使用分布式锁的时候,命名需要管理起来,避免和其他模块和程序产生冲突

    • 事务问题:以下这种情况会先释放锁,然后再提交事务,需要注意。

      @Transactional(rollbackFor = Exception.class)
      public void method(){
      RLock lock = redisson.getLock("qhyu");
      lock.lock();
      // 执行db的insert等操作
      lock.unlock();
      }
      
    • 性能考虑:分布式锁的性能对于高并发场景非常关键。考虑锁的粒度、并发度和锁竞争的情况,以及合理的锁超时时间,以提高系统的性能和响应速度。

    关于分布式锁,作者还有两篇文章可以关联看一下,本文不做赘述了。

    基于Redisson的可重入分布式锁

    基于Redisson的联锁(MultiLock)

你可能感兴趣的:(程序员的日常,java,spring,开发语言,redis,redisson)