Rumah  >  Soal Jawab  >  teks badan

关于使用redis防高并发超中奖品设置过期时间的一个疑问

业务

大转盘抽奖活动 奖品分实物和红包 限制用户只能中一个实物

使用redis防同一用户并发超领实物 即中了多个实物
获得奖池

AwardPool chooseAwardFromPool(){ //得到奖池
    // 查询所有有效奖品
    // 若用户之前已中了实物 排除实物奖品
    if(hasWinedRealObject && award.type==实物)
        continue;
    //...
}
award = chooseAwardFromPool(pool); //从奖池中随机选择一个奖品

若用户还未抽中实物, 且同一用户并发进入, 存在随机选择的奖品都为实物的可能, 如同一用户10个并发请求进来, 其中3个请求碰巧随机选择的奖品均为实物, 于是该用户就能中3个实物, 于是需要引入redis来防并发超中实物. 如下所示

//选中奖品后处理
if(award.type == 实物){ // 若奖品为实物
    key = "user_"+userId+"_实物_count";
    count = redis.incr(key);
    if(count == 1){
        redis.expire(key, 10*60); //设置过期时间10分钟
    }
    if(count > 1){ //同一用户中了多个实物
        award = 未中奖; //此时默认替换为未中奖奖品
    }
}

过期时间我始终不知该如何评估, 设置多长时间合适, 因为基本上是针对恶意用户并发请求才引入redis的, 正常用户的正常页面操作无需做任何处理, 因为若前一次中了实物,后面再来抽奖的话, 一开始取得奖池时就会排除掉实物奖品, 故后面抽奖奖池中压根就没有实物奖品了, 也就不会中实物了.
为什么设置10分钟呢? 因为我觉得两个并发请求--且是均中了实物的两个请求--不可能执行redis.incr(key)时相隔了10分钟, 如下所示

#请求1  用户尚未中实物 从奖池中随机返回了一个实物奖品
award = chooseAwardFromPool(pool); //从奖池中随机选择一个奖品

#请求n  用户尚未中实物 也从奖池中随机返回了一个实物奖品
award = chooseAwardFromPool(pool); //从奖池中随机选择一个奖品

#请求1 执行redis操作
count = redis.incr(key);

#请求n 执行redis操作
count = redis.incr(key);

我觉得10分钟能够保证请求n执行redis操作时, key不会过期, 故能够防超中实物.

但又不是很笃定, 怎觉得存在请求2执行时key会过期的情况, 但又想不出什么情况下会有这样的情况.
请求数并发量特别大的情况下会存在这种可能吗? 如

ab -n 1000000 -c 1000 -T "application/x-www-form-urlencoded" -p post_draw http://localhost:8080/draw

如请求1过来的时候随机选中了一个实物, 等到请求n过来的时候, 请求1还没有提交到数据库中, 于是请求n有可能随机返回一个实物奖品, 等到请求n执行redis.incr(key)时, 已经过了10分钟了, 于是请求n仍能中实物.于是同一用户中了两个实物.

滿天的星座滿天的星座2757 hari yang lalu852

membalas semua(1)saya akan balas

  • PHP中文网

    PHP中文网2017-04-25 09:04:25

    1 Mengikut reka bentuk anda, gunakan redis untuk mengendalikannya. Mengapa anda tidak menetapkan masa kepada kekal? Tunggu permintaan A dihantar sebelum mengosongkannya, dan kemudian ikut pertimbangan logik biasa anda
    2. Tanpa redis, gunakan pangkalan data untuk mencapai kawalan berbilang konkurensi Pertama sekali, anda mesti mempunyai jadual pengumpulan hadiah mempunyai medan yang menunjukkan pemenang Setiap Apabila pengguna memenangi hadiah, jadual kumpulan hadiah akan dikemas kini untuk menetapkan pemenang, dan kemudian anda akan menambah syarat kawalan kuantiti hadiah fizikal apabila mengemas kini SQL

    balas
    0
  • Batalbalas