thinkphp 利用redis 控制并发

author:he
qq:760863706
tp:3.2.3
date:2018-10-19

tp框架开发的项目,需求是想控制某项业务同一时刻的访问量,用redis锁机制来实现目的,在tp公共方法中创建公共函数 concurrence

/**
*redis控制并发
**/
function concurrence(){

    //实例化redis
    $redis = new \Redis();
    $redis->connect(C('REDIS_HOST'),C('REDIS_PORT'));
    $redis->auth(C('REDIS_AUTH'));

    //进入队列及出列,queue在加减的时候,要保证操作的唯一性,此时加锁,完成后在解锁
    $random = mt_rand();//生成随机数
    $start = $redis->set('clock', $random, array('nx', 'ex' => 10));//redis加锁,锁有效期10秒
    while (!$start) 
    {
        usleep(100000);//沉睡100毫秒
        $start = $redis->set('clock', $random, array('nx', 'ex' => 10));//redis加锁,锁有效期10秒
    }
    $queue = $redis->get('queue');
    if ($queue <= 10)
    {
        $redis->incr('queue');//自增
        if ($redis->get('clock') == $random) {//当clock值满足条件
            $redis->del('clock');//删除$random随机数
        }
        $process = '处理具体的业务逻辑中,耗时不定,当前时间戳:'.time();

        $endRandom = mt_rand();//随机数
        $end = $redis->set('clock', $endRandom, array('nx', 'ex' => 10));//redis加锁,锁有效期10秒
        while (!$end) 
        {
            usleep(100000);//沉睡100毫秒
            $end = $redis->set('clock', $endRandom, array('nx', 'ex' => 10));//redis加锁,锁有效期10秒
        }
        $redis->decr('queue');//自减
        if ($redis->get('clock') == $endRandom) {//当clock值满足条件
            $redis->del('clock');//删除$endRandom随机数
        }
        return $process;
    }else{
        if ($redis->get('clock') == $random) {
            $redis->del('clock');
        }
        usleep(200000);//沉睡200毫秒
        concurrence();//递归再次调用
    }

}

在控制器中,调用公共函数,处理相关业务

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ThinkPHP6 Redis 秒杀是指使用 Redis 作为缓存和计数器,实现高并发下的秒杀功能。在秒杀活动中,由于用户量巨大,瞬间的请求量会超过服务器的承受能力,导致系统崩溃或者响应时间过长。而使用 Redis 作为缓存和计数器,可以将请求分散到多个服务器上,避免单点故障,提高系统的稳定性和响应速度。同时,Redis 的原子性操作可以保证秒杀的正确性和公平性,避免出现超卖或者重复购买等问题。 ### 回答2: ThinkPHP6是一款轻量级、高效的PHP框架,提供了非常多的开发组件和工具,支持多种后端数据库和缓存系统。而Redis又是一种高性能的key-value数据存储系统,非常适合用于数据缓存、消息队列、计数器等场景。结合ThinkPHP6框架和Redis缓存系统,可以实现高并发并且高效的秒杀系统。 在ThinkPHP6中使用Redis缓存,需要先配置好redis的连接信息。在config目录下的cache.php文件中,可以进行相关配置,例如: ```php return [ // 缓存配置 'default' => env('cache.driver', 'file'), 'stores' => [ 'file' => [ 'driver' => 'file', 'path' => runtime_path('cache'), ], 'redis' => [ 'driver' => 'redis', 'host' => '127.0.0.1', 'port' => 6379, 'password' => '', 'select' => 0, 'timeout' => 0, 'expire' => 3600, 'persistent' => false, 'prefix' => '', ], ], ]; ``` 然后,在控制器中处理秒杀请求时,可以使用Redis中的事务和机制,保证秒杀过程的原子性和线程安全。例如: ```php public function seckill() { $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $product_id = input('product_id'); $stock_key = 'product:' . $product_id . ':stock'; $user_id = session('user_id'); $buy_key = 'product:' . $product_id . ':user:' . $user_id . ':buy'; // 开启事务 $redis->multi(); // 判断库存是否充足 if ($redis->get($stock_key) <= 0) { $redis->discard(); return json(['code' => -1, 'msg' => '秒杀失败,商品已售罄']); } // 判断用户是否已经购买 if ($redis->get($buy_key) > 0) { $redis->discard(); return json(['code' => -1, 'msg' => '秒杀失败,您已经购买过该商品']); } // 减少库存 $redis->decr($stock_key); // 记录用户已经购买 $redis->incr($buy_key); // 执行事务 $result = $redis->exec(); if ($result) { return json(['code' => 0, 'msg' => '秒杀成功,请尽快支付']); } else { return json(['code' => -1, 'msg' => '秒杀失败,请重新尝试']); } } ``` 以上代码实现了利用Redis的事务和机制,在秒杀请求到来时进行秒杀过程的原子性操作。其中,使用$product_id和$user_id作为key,分别表示商品库存和用户已购买数量,用以保证并发请求的正确性和安全性。 综上所述,ThinkPHP6和Redis的结合使用非常灵活和高效,可以实现各种高并发的应用场景,包括秒杀系统。但同时,由于秒杀系统的特点,需要在代码实现中考虑更多的性能优化和安全性措施,避免出现重大错误和损失。 ### 回答3: ThinkPHP6是一个轻量级PHP框架,可以帮助开发者快速建立Web应用程序。Redis是一个高性能的非关系型内存键值数据库,可以用于存储数据、缓存和消息代理等业务场景。 秒杀是电商业务中常见的一种活动,即在特定时间内限量销售某种商品,通常会引起用户的强烈购买欲望,需要支持高并发、高可靠和高性能的处理方式。 使用ThinkPHP6结合Redis来实现秒杀系统可以采用如下架构: 1. 前端展示层:实现商品展示、倒计时展示、抢购按钮和下单逻辑。 2. 应用层:利用TP6的控制器处理用户请求,调用服务层处理秒杀请求,还可以使用TP6的事件管理器做进一步优化,比如从Redis缓存读取秒杀商品信息,进行幂等性判断等。 3. 服务层:处理商品的库存、订单量、用户秒杀记录等业务逻辑,使用Redis记录秒杀商品的状态(秒杀开始/结束),并提供限流措施,如乐观、悲观、分布式等。 4. 数据层:使用Redis存储秒杀商品信息、秒杀商品数量、用户秒杀信息和订单信息等数据。此处需注意数据存储的结构设计和Redis的线程模型,需要合理利用Redis的命令和批量写入性能。 总的来说,通过结合ThinkPHP6和Redis的强大特性,可以快速搭建一个高性能、可扩展的秒杀系统,提高用户体验,增强品牌价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值