今天面试的时候碰到的一个微信红包的并发问题,有大佬看看有什么最优解吗

设计一个微信红包程序,如何在后台保证不会超发。(比如设定1000个,如何保证并发访问时不会多发)?

php
最佳答案

可以将红包放入队列里面,例如使用redis。当并发的时候,直接从队列里面pop。这样就不会出现多发的问题了。

3年前 评论
Aqua5 (楼主) 3年前
KovenZhang (作者) 3年前
讨论数量: 5
wenqingzzz

最近刚好也在看这个,我在其它地方看的算法

/**
 * 发红包
 * 每次抢到的金额都是剩余金额随机数, 最后一位直接全部获取到就可以了
 * 这里有个问题,第一次抢到的钱应该是最多的,越往后金额越少
 * 优化一下,每次抢到的金额在 1 和 剩余平均值*2 之间
 * @param $money
 * @param $num
 */
function hongBao($money, $num){
    $data = [];
    $leaveMoney = $money;
    for($i = 1; $i <= $num; $i++){
        if($i == $num){
            $data[] = $leaveMoney; // 这里还是最后一个人获取全部的红包
        }else{
            $m = mt_rand(1, $leaveMoney/($num - $i + 1)*2); // 发送红包的金额
            $leaveMoney = $leaveMoney - $m; // 剩余金额
            $data[] = $m;
        }
    }
    $num = 0;
    foreach ($data as $v){
        $num += $v;
    }
    echo "num = ".$num.PHP_EOL;
    print_r($data);
}

// 100块钱发10个红包
hongBao(100, 10);
3年前 评论

并发问题都是转化为非并发,例如提前生成红包,用的时候pop发放

3年前 评论

可以将红包放入队列里面,例如使用redis。当并发的时候,直接从队列里面pop。这样就不会出现多发的问题了。

3年前 评论
Aqua5 (楼主) 3年前
KovenZhang (作者) 3年前

我的想法是生成红包时,先按照人数和金额来随机出每个红包的金额,放进队列中,然后在从队列中取出来

3年前 评论

方案一: 生成 1000 个红包入队 , 每次出队一个

方案二: 每次抢红包的时候加锁 , 会造成性能问题 , 但也可以保证不超发

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!