面试系列28 分布式服务接口的幂等性如何设计

本文阐述了保证接口幂等性的核心原则,即确保每个请求有唯一标识,记录请求处理状态,并检查重复请求,通过示例介绍了如何使用MySQL和Redis实现这一目标。

这个不是技术问题,这个没有通用的一个方法,这个是结合业务来看应该如何保证幂等性的,你的经验。

 

所谓幂等性,就是说一个接口,多次发起同一个请求,你这个接口得保证结果是准确的,比如不能多扣款,不能多插入一条数据,不能将统计值多加了1。这就是幂等性,不给大家来学术性词语了。

 

其实保证幂等性主要是三点:

 

(1)对于每个请求必须有一个唯一的标识,举个例子:订单支付请求,肯定得包含订单id,一个订单id最多支付一次,对吧

 

(2)每次处理完请求之后,必须有一个记录标识这个请求处理过了,比如说常见的方案是在mysql中记录个状态啥的,比如支付之前记录一条这个订单的支付流水,而且支付流水采

 

(3)每次接收请求需要进行判断之前是否处理过的逻辑处理,比如说,如果有一个订单已经支付了,就已经有了一条支付流水,那么如果重复发送这个请求,则此时先插入支付流水,orderId已经存在了,唯一键约束生效,报错插入不进去的。然后你就不用再扣款了。

 

(4)上面只是给大家举个例子,实际运作过程中,你要结合自己的业务来,比如说用redis用orderId作为唯一键。只有成功插入这个支付流水,才可以执行实际的支付扣款。

 

要求是支付一个订单,必须插入一条支付流水,order_id建一个唯一键,unique key

 

所以你在支付一个订单之前,先插入一条支付流水,order_id就已经进去了

 

你就可以写一个标识到redis里面去,set order_id payed,下一次重复请求过来了,先查redis的order_id对应的value,如果是payed就说明已经支付过了,你就别重复支付了

 

然后呢,你再重复支付这个订单的时候,你写尝试插入一条支付流水,数据库给你报错了,说unique key冲突了,整个事务回滚就可以了

 

来保存一个是否处理过的标识也可以,服务的不同实例可以一起操作redis。

### 接口幂等性的定义 接口幂等性指的是同一个请求无论被提交多少次,其产生的效果始终与第一次一致。换句话说,在分布式系统中,即使客户端因网络延迟或其他原因多次发送相同的请求,服务端也能够识别并处理这些重复请求,从而避免数据不一致性或错误操作的发生[^1]。 ### 实现接口幂等性的常见方式 #### 1. 使用唯一标识符(Token) 通过为每次请求分配唯一的标识符(如UUID),并将该标识符存储到数据库或者缓存中。当接收到新的请求时,首先校验此标识符是否存在。如果已存在,则认为这是重复请求,直接返回上次的结果而不重新执行业务逻辑[^4]。 ```java public String handleRequest(String token) { if (cache.exists(token)) { return cache.get(token); } // 执行实际业务逻辑... String result = processBusinessLogic(); // 将结果保存至缓存 cache.put(token, result); return result; } ``` #### 2. 数据库层面的约束设计 利用数据库中的唯一索引来确保某些字段不会因为重复写入而导致异常状态改变。例如,在订单表的设计过程中可以设置`order_number`为主键或者其他形式的独特属性来阻止同一笔交易记录被创建两次以上的情况发生[^5]。 #### 3. 客户端控制重试机制 让前端应用程序负责管理可能存在的超时状况下的再次尝试行为,并且保证每一次新发起的动作都有不同的参数组合传递给后台API调用方[^1]。 ### 常见面试问题及其解答 以下是关于接口幂等性的几个典型提问以及相应的解决方案: 1. **问**: 如何判断一个HTTP方法是否具有天然的幂等特性? - **答**: GET、HEAD、PUT 和 DELETE 方法理论上都是幂等的操作;而 POST 则通常不具备这种性质因为它往往涉及到资源新增这样的动作[^5]。 2. **问**: 设计一个支付系统的流程图说明如何保障整个过程满足幂等等价条件。 - **答**: 流程应包括生成全局唯一ID作为每单交易标志物,在接收到来自用户的购买确认指令之后立即登记这笔账目详情于持久化介质之上再继续后续步骤直到完成全部事务为止[^1]. 3. **问**: 如果发现现有系统里部分重要功能缺乏必要的防重复措施怎么办? - **答**: 应尽快评估影响范围并对受影响模块逐一改造加入合适的去重策略比如引入版本号比较或是基于时间戳过滤等方式减少潜在风险暴露窗口期长度同时也要注意兼容历史遗留数据结构特点以便平稳过渡迁移工作得以顺利开展下去[^2]. ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值