使用redis设计幂等接口
来源:互联网 发布:115个java面试题和答案 编辑:程序博客网 时间:2024/05/16 12:58
幂等:
幂等性是系统的接口对外一种承诺(而不是实现), 承诺只要调用接口成功, 外部多次调用对系统的影响是一致的. 声明为幂等的接口会认为外部调用失败是常态, 并且失败之后必然会有重试举个例子:
有一个订单系统,对外提供了一个处理接口,
如果有个订单001是要扣除用户的100块钱,那么订单001被多次调用,
也只会处理成功一次,也就是只会扣除用户100块。
也可以理解为去除重复调用
订单的状态:
a) 无记录
b) 正在被处理
c) 处理成功
我们需要考虑多种情况:
情况1:
a) a线程开始处理订单001
b) a线程处理订单001成功
c) a线程记录订单001处理成功
情况2:
a) a线程开始处理订单001
b) a线程处理订单001失败,回滚
c) a线程删除订单001的记录
情况3:
a) a线程已成功处理订单001
b) b线程开始处理订单001,发现订单001已经被成功处理,放弃此次处理
情况4:
a) a线程开始处理订单001,正在处理中
b) b线程开始处理订单001,发现订单001正在被处理且未超时,放弃此次处理
情况5:
a) a线程开始处理订单001,且超时了释放了订单001的状态
b) b线程开始处理订单001,发现订单001无人处理,那么锁定订单001开始处理
我们用redis来设计处理的幂等性,但是需要注意的是,这里幂等性的有效期依赖redis的key的生命周期:
a) 正在处理,假设5分钟则认为处理超时(这个值需要根据程序的处理逻辑的超时时间设定)
SET 订单号 时间戳 过期时间
SET 1893505609317740 1466849127 EX 300 NX
b) 成功处理,利用SET的时间戳控制设置权
SET 订单号 成功 过期时间
SET 1893505609317740 0 EX 86400 XX
c) 删除订单,只允许创建者删除,利用SET的时间戳控制删除权
DEL 1893505609317740
# -*- coding: utf-8 -*-import timeimport redisdef check_validity(orderno, del_time): return Truedef deal(): return Trueif __name__ == '__main__': # 连接redis r = redis.StrictRedis(host='localhost', port=6379, db=0) # 订单号 orderno = "1893505609317740" # 当前时间戳 sec = int(time.time()) # 处理超时时间 deal_timeout = 300 # 订单状态保存多久,比如24小时不支付就失效了 del_time = 86400 # 是否成功处理 status = False # 检查订单的有效期 if check_validity(orderno, del_time): print "orderno is ok" else: print "orderno is overdue" exit() # 试图锁住订单 res = r.set(orderno, sec, ex=deal_timeout, nx=True) if res == True: print "set key succeed" else: print "set key failed, key maybe exist, return" exit() # 成功处理了/失败了 status = deal() # 更改订单状态 redis_sec = r.get(orderno) if sec != int(redis_sec): print "check timestamp failed" exit() else: print "check timestamp success" if status == True: # 设置订单处理成功.设置为0 res = r.set(orderno, 0, ex=del_time, xx=True) print "deal succeed: %s" % res else: # 删除订单 res = r.delete(orderno) print "deal failed: %s" % res
小结:
这种设计依然有缺陷,但是能保证大部分的订单是幂等性的,
首先要保证redis是高可用,
其次订单的处理过期时间很重要,不能随意设置,必须根据程序处理流程推理出来,
其次redis的存储空间也影响了订单的状态保存多久。
0 0
- 使用redis设计幂等接口
- API接口非幂等性问题及使用redis实现简单的分布式锁
- redis缓存接口设计
- 接口的幂等性设计
- 分布式系统接口幂等性设计
- 分布式系统的接口幂等性设计
- 分布式后端接口幂等性设计思路
- redis C接口hiredis初次使用
- redis C接口hiredis初次使用
- redis C接口hiredis初次使用
- redis使用(四):C 同步接口
- redis使用(五):c异步接口
- 接口的幂等性
- 接口幂等的重要性
- http接口幂等性
- 接口的幂等性
- 接口的幂等性
- spring整合redis客户端及缓存接口设计
- 整数拆分 整合算法
- 101. Symmetric Tree 对称树 (难点!)
- Ad-hoc类型同步识别
- Android EditView 输入限制(软键盘限制)
- 大型网站的架构和演变-引子
- 使用redis设计幂等接口
- 学习Java中遇到的一些问题
- Block语法基础
- 【软件开发工具——陌生的熟悉人】
- Pythagoras's Revenge
- 基于布尔注入的Python代码
- Promise 简介
- StudyJams-第07课_面向对象和创建实例
- CSS权威指南-line-height缩放因子