当前位置: 首页 > 科技观察

阿里面试官:如何设计接口的幂等性?

时间:2023-03-23 12:07:11 科技观察

大家好,我是Kuangchat。最近负责的接口都涉及到幂等操作,所以抽空总结一下。这也是面试官爱问的问题。1、什么是幂等?看看维基百科是怎么说的:幂等性:多次调用一个方法或接口不会改变业务状态,可以保证多次调用的结果与单次调用的结果一致。二、使用幂等性的场景1、当前端重复提交用户注册、用户创建商品等操作时,前端会提交一些数据给后台服务,后台需要根据创建记录在数据库中用户提交的数据。如果用户不小心点击了几次,后台收到了几次提交,就会在数据库中重复创建多条记录。这是接口幂等性不足导致的bug。2.接口超时重试对于第三方调用的接口,可能会因为网络原因导致调用失败。这时一般会在设计时在接口调用中加入失败重试机制。如果第一次调用中途,就会出现网络异常。此时再次调用时,会因为脏数据的存在而出现调用异常。3、消息重复消费使用消息中间件处理消息队列时,手动ack确认消息正常消费。如果消费者突然断开连接,未完成的消息将被放回队列中。当消息被其他消费者重新消费时,如果没有幂等性,重复消息消费的结果会出现异常,如数据库重复数据、数据库数据冲突、资源重复等。三、解决方案1、token机制实现通过token机制实现接口的幂等性,是一种比较通用的实现方式。示意图如下:具体流程步骤:客户端首先会发送请求获取token,服务端会生成一个全局唯一的ID作为token保存在redis中,并将这个ID返回给客户端。客户端第二次调用业务请求。服务器校验token时必须携带此token。如果校验成功,则执行业务,删除redis中的token。如果检查失败,说明redis中没有对应的token。意思是重复操作,直接返回。指定结果需要客户端注意:推荐使用lua脚本实现redis中是否有token,删除代码逻辑保证原子性。全局唯一ID可以通过百度的uid-generator和美团的Leaf来生成。2、基于MySQL这种实现是基于mysql独有的索引特性。示意图如下:具体流程步骤:创建去重表,其中需要对某个字段建立唯一索引。每个字段都有一个唯一的索引。如果插入成功,则证明表中没有该请求的信息,会执行后续的业务逻辑。如果插入失败,说明当前请求已经执行完毕,直接返回。3、基于SETNX命令的RedisSETNX键值实现本实现:当且仅当key不存在时,将key的值设置为value。如果给定的键已经存在,SETNX什么也不做。该命令在设置成功时返回1,在设置失败时返回0。示意图如下:具体流程步骤:客户端首先向服务器发起请求,会得到一个唯一的可以代表所请求业务的字段,将该字段以SETNX的形式存储在redis中,并根据设置相应的超时时间到企业。如果设置成功,证明这是第一次请求,然后执行后续的业务逻辑。如果设置失败,说明当前请求已经执行完毕,直接返回summary。机器、悲观锁、乐观锁都比较简单。总之,当你设计一个接口时,幂等性是首要考虑的,尤其是当你负责设计涉及金钱的转账和支付接口时,一定要特别注意!

猜你喜欢