老大让我做个红包雨的功能,主要写后端,暂时没想到好的实现思路~ - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Waterchestnut
V2EX    Java

老大让我做个红包雨的功能,主要写后端,暂时没想到好的实现思路~

  •  
  •   Waterchestnut 2017-04-11 15:49:28 +08:00 8213 次点击
    这是一个创建于 3117 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我打算这么设计,给前端提供一个 htttp 接口,接口请求过来随便发放金额,诶,这个红包概率怎么控制?后面用原子计数器来计算红包数量,当达到老大给的数量上线和金额上线就告诉用户抢完了= =貌似 这样太粗糙。。暂时也想到好的解决方案

    第 1 条附言    2017-04-12 00:34:39 +08:00
    1.目前金额也不是完全随机,有备选额度,比如 1 , 2 , 5 , 10 ,在这里面金额随机。
    2.红包雨一次下 50 个,用户最多点中 40 个,当然是点中也不一定有红包,概率我打算定在 5%
    3.抢红包总会会狂点,预计我上 redis ,做的队列啥的待我研究一下
    4.楼主渣后台 (") ,没有高并发经验,害怕.jpg
    34 条回复    2017-04-12 11:05:57 +08:00
    MrFireAwayH
        1
    MrFireAwayH  
       2017-04-11 15:56:49 +08:00
    红包写最高 8888

    后端控制下随机生成 0~50 的数
    subdued
        2
    subdued  
       2017-04-11 15:59:21 +08:00
    关注一波
    torbrowserbridge
        3
    torbrowserbridge  
       2017-04-11 15:59:29 +08:00
    上线后请 @ 我 URL 页面,谢谢
    Troevil
        4
    Troevil  
       2017-04-11 15:59:41 +08:00
    奖池机制,先分配好奖池,然后在奖池里面随机抽取.
    6IbA2bj5ip3tK49j
        5
    6IbA2bj5ip3tK49j  
       2017-04-11 16:02:44 +08:00
    先把红包生成好。再随机发出去。发完就暂停。搞得细的话,还可以按小时分。
    A3m0n
        6
    A3m0n  
       2017-04-11 16:03:06 +08:00   1
    前些天做了个巨粗糙的抢红包
    https://ooo.0o0.ooo/2017/04/11/58ec8cc8b4243.png
    就是想模拟一下微信的抢红包算法
    算法参考下面这个回答
    https://www.zhihu.com/question/22625187
    bramblex
        7
    bramblex  
       2017-04-11 16:05:12 +08:00
    @MrFireAwayH 花雅酱上班摸鱼~
    jianzhiyao020
        8
    jianzhiyao020  
       2017-04-11 16:30:02 +08:00
    第一步:离线生成相应数量和金额上线的红包队列
    第二步:写代码去抢啊,控制好冲突
    第三步:也是最重要的一步,上线后请通知我。
    xiaoyang7545
        9
    xiaoyang7545  
       2017-04-11 16:33:27 +08:00
    @jianzhiyao020 这种东西如果用数据库实现好像就会有 冲突(后一个查询请求到来时,前面的未更新)。用什么方式防止冲突比较好?
    gamexg
        10
    gamexg  
       2017-04-11 16:51:25 +08:00
    预先生成红包,然后抢的时候直接 UPDATE 一条所有者是空的红包,将所有者设置为当前用户。
    之后在执行次查询找到被更新的红包。

    如果允许抢多个红包,那么更新时记得加个随机数,查询时带上好区分多个红包。

    当然上 Redis ,用队列功能更简单。
    rswl
        11
    rswl  
       2017-04-11 16:54:06 +08:00
    上线记得喊一下
    AlisaDestiny
        12
    AlisaDestiny  
       2017-04-11 17:03:05 +08:00
    可以预计算一个分配数组比如[0,1,0,,0,1].这样的话就是第二个人和第四个人有红包。可以控制概率。但是要做好每个用户抢的次数限制。
    AlisaDestiny
        13
    AlisaDestiny  
       2017-04-11 17:04:13 +08:00
    尴尬。写错了。是[0,1,0,0,1] 第二个和第五个。
    jianzhiyao020
        14
    jianzhiyao020  
       2017-04-11 17:36:22 +08:00   2
    @xiaoyang7545
    redis 单线程帮到你,
    可以用队列的形式存储红包数据,
    速度快,
    且数据不会有冲突。

    mysql 的话,
    首先可能想到的是锁:
    可以在务中 select ... for update 锁住该行队列数据,
    不让别人修改。
    并在 update 的条件中中做好控制即可。
    这样的话可能会产生这个队列阻塞问题,
    需要用哈希随机碰撞红包,
    但是这样也同样会可能红包比较难碰撞的问题。

    其实还可以这样做,
    用一个新表去做,
    主键子增,
    通过插入记录获得 last_insert_id ,
    再去红包表获取数据,
    简单容易实现,
    且不会有冲突的问题。


    mysql 最好结合 redis ,
    redis 计数, mysql 存储。

    有错希望能够及时提出,感谢。
    banksiae
        15
    banksiae  
       2017-04-11 17:41:05 +08:00   1
    不需要预分配,只要设置总额和个数就行了,金额随机生成, redis 做原子控制,防止刷红包,算法参考 A3m0n 提到的。
    有个问题,抢红包人数多的话,就成了秒杀场景,所以抢之前要做下类似红包结束的判断。
    最后就是异步发红包的问题,流水不能出错,保证幂等,基本就 OK 了
    luluuulu4848
        16
    luluuulu4848  
       2017-04-11 17:41:23 +08:00   1
    @xgfan 好主意啊
    luluuulu4848
        17
    luluuulu4848  
       2017-04-11 17:43:25 +08:00
    @banksiae 为什么不需要预分配,我觉得挺好的 先生成出来,求教
    banksiae
        18
    banksiae  
       2017-04-11 17:57:38 +08:00
    @luluuulu4848 浪费存储空间,如果有 mysql 做,会有点性能问题;如果用 redis 预存储,浪费空间
    quickma
        19
    quickma  
       2017-04-11 23:55:33 +08:00
    多少的量?少的话预分配最稳。
    Waterchestnut
        20
    Waterchestnut  
    OP
       2017-04-12 00:15:31 +08:00 via Android
    @MrFireAwayH 金额随机数为 1 , 2 , 3 , 5 , 10 ,在这几个数中随机,当然小额红包中奖率高一些
    Waterchestnut
        21
    Waterchestnut  
    OP
       2017-04-12 00:15:38 +08:00 via Android
    Waterchestnut
        22
    Waterchestnut  
    OP
       2017-04-12 00:17:05 +08:00 via Android
    @Troevil 奖金池是个思路,但是这也相当于是个库存模块了,怎么防止超卖
    Waterchestnut
        23
    Waterchestnut  
    OP
       2017-04-12 00:17:37 +08:00 via Android
    @xgfan ok ,感谢
    Waterchestnut
        24
    Waterchestnut  
    OP
       2017-04-12 00:18:19 +08:00 via Android
    @A3m0n 谢谢大神的 demo
    Waterchestnut
        25
    Waterchestnut  
    OP
       2017-04-12 00:19:16 +08:00 via Android
    Waterchestnut
        26
    Waterchestnut  
    OP
       2017-04-12 00:22:32 +08:00 via Android
    @AlisaDestiny 目前一个人抢红包的数量没有限制,在 30 秒内能抢多少是多少
    Waterchestnut
        27
    Waterchestnut  
    OP
       2017-04-12 00:23:35 +08:00 via Android
    @AlisaDestiny 这意思是提前就定好哪个次序的用户可以得到红包哈?
    Waterchestnut
        28
    Waterchestnut  
    OP
       2017-04-12 00:24:24 +08:00 via Android
    @jianzhiyao020 非常感谢(ω`)
    Waterchestnut
        29
    Waterchestnut  
    OP
       2017-04-12 00:28:41 +08:00 via Android
    @banksiae 确实就是秒杀场景了,预计 20 万个红包,,一次红包雨 50 个,单个用户最多领取 40 ,里面有的是空的,这种情况下,用户一定会狂点。
    Waterchestnut
        30
    Waterchestnut  
    OP
       2017-04-12 00:36:59 +08:00 via Android
    @x7395759 老大说预计 20 万个红包,当然有没有这么多人点我就不知道了。。。
    azh7138m
        31
    azh7138m  
       2017-04-12 08:24:59 +08:00 via Android
    @A3m0n 知乎那个太假,不如直接拿分做单位,浮点太坑
    liuxu
        32
    liuxu  
       2017-04-12 09:29:23 +08:00
    这我得写脚本抢了
    jason19659
        33
    jason19659  
       2017-04-12 10:10:26 +08:00
    预计好人数,提前生成好红包扔进一个线程安全的队列,怎么样
    hongcha
        34
    hongcha  
       2017-04-12 11:05:57 +08:00
    艺术来源于生活,
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1084 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 17:56 PVG 01:56 LAX 10:56 JFK 13:56
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86