通过flask+redis(hash,list)实现电子商务系统中抢购(秒杀)时,每个用户只能抢购一个,库存不会为负数的情况。

今天面试了 一家非常高大上的公司,问了我关于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个商品。

 

版权声明:本文为rgcLOVEyaya原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_836days.html