• laravel基于redis实现的一个简单的秒杀系统


    说明:网上很多redis秒杀系统的文章,看的都是一头雾水,然后自己来实现一个,也方便以后自己学习

    实现的方式是用的redis的list队列,框架为laravel

    核心部分为list的pop操作,此操作为原子性,即使很多用户同时到达,也是依次执行

    示例:

    <?php
    /**
     * Created by PhpStorm.
     * User: chenyRain
     * Date: 2018/5/28
     * Time: 11:36
     */
    
    namespace AppHttpControllers;
    
    
    use IlluminateSupportFacadesRedis;
    
    class RedisController extends Controller
    {
        public $user_number = 50; // 允许进入队列的人数
    
        /**
         * 这个方法,相当于点击进入商品详情页,开启秒杀活动
         */
        public function index()
        {
            $goods_number = 10; // 商品库存数量为10
    
            if (! empty(Redis::llen('goods_name'))) {
                echo '已经设置了库存了';
                exit;
            }
    
            // 初始化
            Redis::command('del', ['user_number', 'success']);
    
            // 将商品存入redis链表中
            for ($i = 1; $i <= $goods_number; $i++) {
    
                // lpush从链表头部添加元素
                Redis::lpush('goods_name', $i);
            }
    
            // 设置过期时间
            $this->setTime();
    
            // 返回链表 goods_name 的长度
            echo '商品存入队列成功,数量:'.Redis::llen('goods_name');
        }
    
        public function setTime()
        {
            // 设置 goods_name 过期时间,相当于活动时间
            Redis::expire('goods_name', 120);
        }
    
    
        /**
         * 这个方法,相当于点击 抢购 操作
         */
        public function start()
        {
            $uid = mt_rand(1, 99); // 假设用户ID
    
            // 如果人数超过50,直接提示被抢完
            if (Redis::llen('user_number') > $this->user_number) {
                echo '遗憾,被抢完了';
                exit;
            }
    
            // 获取抢购结果,假设里面存了uid
            $result = Redis::lrange('success', 0, 20);
            // 如果有一个用户只能抢一次,可以加上下面判断
            if (in_array($uid, $result)) {
                echo '你已经抢过了';
                exit;
            }
    
            // 将用户加入队列中
            Redis::lpush('user_number', $uid);
    
            // 从链表的头部删除一个元素,返回删除的元素,因为pop操作是原子性,即使很多用户同时到达,也是依次执行
            $count = Redis::lpop('goods_name');
            if (! $count) {
                echo '被抢完了';
                exit;
            }
    
            $msg = '抢到的人为:'.$uid.',商品ID为:'.$count;
            Redis::lpush('success', $msg);
            echo '公司拟,抢到了';
        }
    
        /**
         * 查看抢到结果
         */
        public function result()
        {
            $result = Redis::lrange('success', 0, 20);
            dd($result);
        }
    }

    说明一下:

      1、首先运行index方法设置商品库存,并初始化结果队列和用户队列

      2、运行start方法来抢购

    下面配上ab测试结果

    附上抢到的人名单

  • 相关阅读:
    【BZOJ2127】happiness 最小割
    【xsy2748】 fly 矩阵快速幂
    [BZOJ2758] [SCOI2012]Blinker的噩梦 扫描线+set
    【BZOJ2732】【HNOI2012】射箭 二分+半平面交
    【xsy1162】鬼计之夜 最短路+二进制拆分
    【xsy2111】 【CODECHEF】Chef and Churus 分块+树状数组
    【xsy1116】数学题 奥数题
    【CODECHEF】Children Trips 倍增
    【xsy1098】第k小 可持久化trie
    扩展中国剩余定理(扩展CRT)详解
  • 原文地址:https://www.cnblogs.com/chenhaoyu/p/9100641.html
Copyright © 2020-2023  润新知