§ Essay

幂等性通用解决方案

讲解幂等性通用解决方案,详解大厂面试考察维度

Harper · · 4 min read · —

大型企业需要构建稳定可靠的系统,而幂等性是实现这一目标的关键。在面试中,大厂经常会考察应聘者对于幂等性的掌握程度,掌握幂等性的程序员能够设计出更加稳定、高效的系统,符合大厂对技术人才的高要求。


一、初识幂等

1、什么是幂等

  • 在计算机科学和网络通信中,幂等指一个操作无论执行多少次,其结果都是一致的
  • 换句话说,对于相同的输入,无论进行多少次重复操作,都应该保持其结果一致

1

数学来源:

f(f(x))=f(x)f(f(x)) = f(x)

哪操作会导致幂等?

  • 读:不对底层数据产生变化,天然支持幂等

    如 HTTP: GET
  • 写:会修改底层数据,无法保证幂等

    如 HTTP: POST/DELETE/PUT

2、幂等产生的原因

在 Web 应用程序中,导致幂等的原因一般分为:

  • 网络延迟导致的请求重试
  • 前端用户的重复操作请求
  • 第三方中间件的重试机制(如 MQ)

当重复请求(相同输入的重复操作)进入系统中时,如果接口不具备幂等性,可能会导致:

  • 状态不一致
  • 数据重复提交

二、幂等场景与解决方案

1、幂等场景

(1)前端重复提交

2

(2)消息重复消费

5

当消费者出现异常后,默认策略是消息会不断 requeue(重新入队)到队列,再重新发送给消费者,然后再次异常,再次 requeue,无限循环,导致 mq 的消息处理飙升,带来不必要的压力

我们可以利用 Spring 的 retry 机制,在消费者出现异常时利用本地重试,而不是无限制的 requeue 到 mq 队列

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1
        retry:
          enabled: true # 开启消费者失败重试
          initial-interval: 1000 # 初始的失败等待时长为1秒
          multiplier: 1 # 下次失败的等待时长倍数,下次等待时长 = multiplier * last-interval
          max-attempts: 3 # 最大重试次数
          stateless: true # true无状态;false有状态。如果业务中包含事务,这里改为false

(3)任务重复执行

2、幂等解决方案

(1)token 机制 —— 前端重复提交

3

4

(2)分布式锁 —— 消息重复消费

加锁成功返回 ok,java 代码被封装后返回 true

如果同一个 key 加锁后过期时间还没到,返回: nil

可以借助 ttl key 查看过期时间

6


三、面试

1、说说你对于幂等的理解

  • 相同输入的重复操作,其结果应该保持一致
  • 如 HTTP 的读操作,如 GET 协议天然就是支持幂等,而对于写操作,如 POST / PUT / DELETE 是需要程序员做幂等处理的

2、有哪些常见的幂等场景

  • 网络延迟导致的请求重试
  • 前端用户的重复操作请求
  • 第三方中间件的重试机制(如 MQ)