今天面试了 一家非常高大上的公司,问了我关于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实现抢购(秒杀)功能的更多相关文章

  1. redis实现高并发下的抢购/秒杀功能

    之前写过一篇文章,高并发的解决思路(点此进入查看),今天再次抽空整理下实际场景中的具体代码逻辑实现吧:抢购/秒杀是如今很常见的一个应用场景,那么高并发竞争下如何解决超抢(或超卖库存不足为负数的问题)呢 ...

  2. thinkphp+redis实现秒杀功能

    好久没来整理文章了,闲了没事写篇文章记录下php+redis实现商城秒杀功能. 1,安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下) 1.1,安装 php_igbi ...

  3. PHP和Redis实现在高并发下的抢购及秒杀功能示例详解

    抢购.秒杀是平常很常见的场景,面试的时候面试官也经常会问到,比如问你淘宝中的抢购秒杀是怎么实现的等等. 抢购.秒杀实现很简单,但是有些问题需要解决,主要针对两个问题: 一.高并发对数据库产生的压力二. ...

  4. php+redis实现电商秒杀功能

    这一次总结和分享用Redis实现分布式锁来完成电商的秒杀功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说分享思路比分享代码更重要(貌似大概是这个意思,若有误请谅解 ...

  5. spring boot:redis+lua实现生产环境中可用的秒杀功能(spring boot 2.2.0)

    一,秒杀需要具备的功能: 秒杀通常是电商中用到的吸引流量的促销活动方式 搭建秒杀系统,需要具备以下几点: 1,限制每个用户购买的商品数量,(秒杀价格为吸引流量一般会订的很低,不能让一个用户全部抢购到手 ...

  6. Redis+Lua解决高并发场景抢购秒杀问题

    之前写了一篇PHP+Redis链表解决高并发下商品超卖问题,今天介绍一些如何使用PHP+Redis+Lua解决高并发下商品超卖问题. 为何要使用Lua脚本解决商品超卖的问题呢? Redis在2.6版本 ...

  7. Redis事务和实现秒杀功能的实现

    今天带着学生学习了Redis的事务功能,Redis的事务与传统的关系型数据库(如MySQL)有所不同,Redis的事务不能回滚. Redis中使用multi.exec.discard.watch.un ...

  8. Redis分布式锁实现简单秒杀功能

    这版秒杀只是解决瞬间访问过高服务器压力过大,请求速度变慢,大大消耗服务器性能的问题. 主要就是在高并发秒杀的场景下,很多人访问时并没有拿到锁,所以直接跳过了.这样就处理了多线程并发问题的同时也保证了服 ...

  9. Redis两种秒杀抢购思路

    方式一:使用DECR减库存 /** * 外卡进入减库存 * @param competitionQuarterInDTO * @return */@Overridepublic int otherCa ...

随机推荐

  1. Jmeter 非 GUI 命令行执行脚本文件

    https://www.cnblogs.com/yebaofang/p/9803273.html

  2. Linux常用文件操作命令

    一.进入文件夹  格式:cd [目录名称]  常用选项: cd /  进入当前目录 cd .. 返回上一级目录.  cd ../.. 将当前目录向上移动两级.  cd - 返回最近访问目录. 二.显示 ...

  3. HTML5-全局属性

    HTML5-全局属性 HTML 属性赋予元素意义和语境.全局属性可用于任何 HTML 元素. contentEditable - 规定元素内容是否可编辑.- 注释:如果元素未设置 contentedi ...

  4. webbug3.0靶场第一关

    目标一,由于用的kli系统,所以没有去手动注入,用了sqlmap来注入检测 先用sqlmap -u "http://192.168.199.136/pentest/test/sqli/sql ...

  5. C++中const的用法

    1.const修饰普通变量和指针 (1).const修饰普通变量 其写法有2种:a.const type value;   b.type const value; 这两种写法本质上是一样的.其含义是: ...

  6. javascript 创建节点和新增节点

    createElement(tabName) 创建一个为tagName的新元素节点 ANode.appendChild(BNode)把B节点追加至A节点的末尾 insertBefore(ANode,B ...

  7. JavaList列表的一些方法

    import java.util.ArrayList;import java.util.Iterator;import java.util.List; public class Test1 { pub ...

  8. Linux 连接mysql

    连接MYSQL: 格式: mysql -h主机地址 -u用户名 -p用户密码 1.例1:连接到本机上的MYSQL 找到mysql的安装目录,一般可以直接键入命令mysql -uroot -p,回车后提 ...

  9. 学习3DES加密算法笔记

    3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称.它相当于是对每个数据块应用三次DES加密算法.由于计 ...

  10. 1、Nexus安装

    1.nexus 下载地址: https://sonatype-download.global.ssl.fastly.net/nexus/oss/nexus-2.14.5-02-bundle.tar.g ...