flask+redis实现抢购(秒杀)功能
今天面试了 一家非常高大上的公司,问了我关于redis的实用性问题,但是答的不是很好,所以下午通过再次学习 redis,实现相关实用性功能的一种。
对于抢购功能,难点在于 抢购时 由于高并发请求,导致一个用户抢购多件商品,库存量小于订单量的情况。
如下通过redis的hash和list类型实现相关功能。
思路:
hash:主要用来存储用户抢购成功的信息,因其自身的特性,如果hash的key,val重复,会返回0,从而判断一个用户只能抢购一个商品。
list:主要用来存放商品,在每个请求进来时,从list中pop一个商品,这样做到针对redis(货物)做到单线程(无论并发多少个请求)。
整体思路:利用hash的不可重复特性和list, 在请求进来时从list中pop一个商品,然后添加到hash中,如果添加失败,就再次push一个商品到list中。
- from flask import Flask, request
- from flask.views import MethodView
- app = Flask(__name__)
- REDIS_CONF = {
- 'host': '127.0.0.1',
- 'port': 6379,
- 'db': 1
- }
- app.config.update({'REDIS_CONF': REDIS_CONF})
- from redis import StrictRedis
- import random
- REDIS = StrictRedis(**REDIS_CONF)
- class GetGoods(MethodView):
- def post(self):
- uid = random.randint(1, 10)
- if REDIS.lpop('goods_list'):
- if REDIS.hset('user_list', uid, 1):
- print(f'Success,{uid}')
- return f'Success,{uid}'
- else:
- # 不可重复抢(每人限领一个)
- print(f'push ,{uid}')
- REDIS.lpush('goods_list', 1)
- return f'create a user {uid}'
- else:
- # 已抢完
- print('Finsh!')
- return 'Finsh!'
- def get(self):
- user_list = REDIS.hgetall('user_list')
- user_list_len = REDIS.hlen('user_list')
- goods_list = REDIS.llen('goods_list')
- result_dict = {"user_list": user_list, "user_list_len": user_list_len, 'goods_list': goods_list}
- print(result_dict)
- return 'success!'
- class SendGoods(MethodView):
- def post(self):
- count = request.form.get('count')
- if REDIS.exists('goods_list'):
- print('delet exists goods')
- REDIS.delete('goods_list')
- for item in range(int(count)):
- REDIS.lpush('goods_list', 1)
- REDIS.delete('user_list')
- goods_list = REDIS.lrange('goods_list', 0, count)
- return f'send goods success! {goods_list}'
- # 用户抢购接口
- app.add_url_rule('/goods', view_func=GetGoods.as_view('goods'), methods=['POST'])
- # 商家查看商品抢购结果
- app.add_url_rule('/goods', view_func=GetGoods.as_view('get_goods'), methods=['GET'])
- # 商家发布商品
- app.add_url_rule('/send/goods', view_func=SendGoods.as_view('send_goods'), methods=['POST'])
- app.run(host='127.0.0.1', port=8000, threaded=10, debug=True)
通过postman测试:
先执行 商家发布商品 接口,发送100个商品。
然后并发压力测试 商家查看商品抢购结果 接口。
然后执行 商家查看商品抢购结果 接口得到如下结果:
发布100个商品,只有10个人抢购1000此,结果做到了每人一个商品,剩下90个商品。
flask+redis实现抢购(秒杀)功能的更多相关文章
- redis实现高并发下的抢购/秒杀功能
之前写过一篇文章,高并发的解决思路(点此进入查看),今天再次抽空整理下实际场景中的具体代码逻辑实现吧:抢购/秒杀是如今很常见的一个应用场景,那么高并发竞争下如何解决超抢(或超卖库存不足为负数的问题)呢 ...
- thinkphp+redis实现秒杀功能
好久没来整理文章了,闲了没事写篇文章记录下php+redis实现商城秒杀功能. 1,安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下) 1.1,安装 php_igbi ...
- PHP和Redis实现在高并发下的抢购及秒杀功能示例详解
抢购.秒杀是平常很常见的场景,面试的时候面试官也经常会问到,比如问你淘宝中的抢购秒杀是怎么实现的等等. 抢购.秒杀实现很简单,但是有些问题需要解决,主要针对两个问题: 一.高并发对数据库产生的压力二. ...
- php+redis实现电商秒杀功能
这一次总结和分享用Redis实现分布式锁来完成电商的秒杀功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说分享思路比分享代码更重要(貌似大概是这个意思,若有误请谅解 ...
- spring boot:redis+lua实现生产环境中可用的秒杀功能(spring boot 2.2.0)
一,秒杀需要具备的功能: 秒杀通常是电商中用到的吸引流量的促销活动方式 搭建秒杀系统,需要具备以下几点: 1,限制每个用户购买的商品数量,(秒杀价格为吸引流量一般会订的很低,不能让一个用户全部抢购到手 ...
- Redis+Lua解决高并发场景抢购秒杀问题
之前写了一篇PHP+Redis链表解决高并发下商品超卖问题,今天介绍一些如何使用PHP+Redis+Lua解决高并发下商品超卖问题. 为何要使用Lua脚本解决商品超卖的问题呢? Redis在2.6版本 ...
- Redis事务和实现秒杀功能的实现
今天带着学生学习了Redis的事务功能,Redis的事务与传统的关系型数据库(如MySQL)有所不同,Redis的事务不能回滚. Redis中使用multi.exec.discard.watch.un ...
- Redis分布式锁实现简单秒杀功能
这版秒杀只是解决瞬间访问过高服务器压力过大,请求速度变慢,大大消耗服务器性能的问题. 主要就是在高并发秒杀的场景下,很多人访问时并没有拿到锁,所以直接跳过了.这样就处理了多线程并发问题的同时也保证了服 ...
- Redis两种秒杀抢购思路
方式一:使用DECR减库存 /** * 外卡进入减库存 * @param competitionQuarterInDTO * @return */@Overridepublic int otherCa ...
随机推荐
- Python学习之路并发编程--信号量、事件、队列及生产消费模型
1. 信号量 对于多进程来说,多个进程同时修改数据,就可能出现安全隐患,所以引入了锁,这一机制,但锁只能有一把来控制一个的开关,当你需要几把锁的时候,就可能用到信号量的概念.他是用了锁的原理,内置了一 ...
- JDK无法卸载问题解决
在控制面板卸载JDK时,显示正在收集删除文件,进度条满了之后就闪退了,但JDK还在,试了几次都是如此. 后来,发现微软官方出了“修复阻止程序安装或删除的问题”的应用,可以自动修复包括阻止你安装或删除程 ...
- python基础(九)
一.私有 class DB: port = 3306 #类变量 def __init__(self): self.host = '127.0.0.1' self.__user = 'root' #实例 ...
- css常用样式总结:
一.input和textarea修改placeholder的颜色: input::-webkit-input-placeholder { /* WebKit browsers */ color: #c ...
- git 提交本地工程
1> 进入github 建立repository 2> 得到git master 地址 3> 得到进入本地工程目录 右键->git bash here 4>执行 以下命令 ...
- superReducedString-hankerrank
Steve has a string of lowercase characters in range ascii[‘a’..’z’]. He wants to reduce the string t ...
- Assembly Experiment9
用英文写太浪费时间了,而且书上的讲解对各种功能的英文原句少之又少,有空还是看龙书吧(不存在的) 实验1: 十六进制转换十进制 实验代码: ; 在屏幕上输出内存单元中的十进制两位数 assume cs: ...
- C++——volatile关键字的学习
首先声明一点,本文是关于volatile关键字的学习,学习内容主要是来自一些大牛的网络博客. 一篇是何登成先生的C/C++ Volatile关键词深度剖析(http://hedengcheng.com ...
- websocket 2 rest api
需要开发一个prometheus 的exporter 使用jmespath 获取对应metrics的数据,并进行转换处理,但是因为那个服务 提供的接口是通过websoket 的实时api,所以基于no ...
- #Windows# 删除桌面删除不了文件夹
问题:某个文件夹直接删除提示找不到. 解决方法:进入命令行,使用rmdir命令,删除成功. 具体命令为: cd /d D:\Desktop //使用/d可以改变驱动器,不用这个参数只能在同一个驱动器里 ...