flask+redis實現搶購(秒殺)功能
阿新 • • 發佈:2018-12-17
今天面試了 一家非常高大上的公司,問了我關於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個商品。