zoukankan      html  css  js  c++  java
  • php之yii2简单分布式redis锁限制和缓存设置

    原文作者: xingguang
    原文链接:https://www.tiance.club/post/2709942805.html

    yii2框架简单加锁锁定本次任务没执行完之前不允许再请求本次方法,注意这只是简单实现能应对几乎所有并发场景。

    /**
         * 具体业务逻辑代码
         */
        public function business(){
            $key ='redis_key_name:'.'订单id或其他本次锁的唯一值';
    
            self::lockLimit($key);
    
    //        //这里需要用try catch,防止中途出异常,导致没解锁
            try {
                //具体处理的业务逻辑代码
                Yii::$app->redis->del($key); //业务逻辑处理完毕,解锁
            } catch (Throwable $e) {
                Yii::$app->redis->del($key); //业务逻辑处理失败,还是解锁
                //日志方法,具体自己实现
                CoreHelper::write(json_encode(['eventName','order_id'=>$order->order_id??'',$e->getMessage()], JSON_UNESCAPED_UNICODE));
            }
        }
    
        /**
         * redis锁限制(设置锁的时间,具体看自己的业务场景,如果是限制手速的一般设置1秒,如果是限制本次情况处理完前不接受其他请求的一般设置120秒(一个接口请求一般不超过120秒))
         * $key 要限制的用户或订单唯一key值 ($key='redis_key_name:'.'订单id或其他本次锁的唯一值';)
         * $scene 场景 1、手速限制 2、处理事务限制
         * $expire 锁有效期,默认是有1和120秒的设置
         */
        public static function lockLimit($key,$scene=2,$expire=0){
            $redis=Yii::$app->redis;
            $lock_result = $redis->setnx($key,1);
            if($scene==1)$redis->expire($key, empty($expire)?1:$expire);
    
            //判断不是空直接中断本次操作
            if (!$lock_result) {
                //随便你们return或其他友好输出,下面的输出只是个人示例
                throw new Exception('-1000', "亲,太过频繁对身体不好");
            }
            if($scene==2)$redis->expire($key, empty($expire)?120:$expire);
        }
    

    原文作者: xingguang
    原文链接:https://www.tiance.club/post/2709942805.html

    缓存设置

    		$key='redis_key_name';
            $key_data=Yii::$app->redis->get($key);
            //判断不是空直接中断本次操作
            if(!empty($key_data)){
                //随便你们return或其他友好输出,下面的输出只是个人示例
                retrun json_decode($key_data,true);
            }
            
    
            //这里需要用try catch,防止中途出异常,导致没解锁
            try {
                //具体处理的业务逻辑代码
                $data=['内容'];
                //确定没锁后先赋值redis,锁上先
                Yii::$app->redis->set($key,json_encode($data));
                Yii::$app->redis->expire($key, 300); 
            } catch (Throwable $e) {
                //日志方法,具体自己实现
                CoreHelper::write(json_encode(['eventName','order_id'=>$order->order_id??'',$e->getMessage()], JSON_UNESCAPED_UNICODE));
            }
    

    注意:
    1、Throwable为php7及以上版本的万能捕获任何异常,php7以下版本用:Exception
    2、请确定自己已经在配置文件配置redis配置
    找到config/development.php(开发环境)或config/production.php(生产环境),在'components' => []中加入,如:

        'components' => [
        	'redis' => [
                'class' => 'BaseComponentsaseRedisConn',
                'hostname' => '127.0.0.1',
                'port'     => 6379,
            ],
        ]
    

    3、Yii如果找不到请在命名空间后加 use Yii;

    原文作者: xingguang
    原文链接:https://www.tiance.club/post/2709942805.html

  • 相关阅读:
    《web-Mail服务的搭建》
    VMware虚拟机三种联网方法及原理
    Java总结——常见Java集合实现细节(1)
    nginx静态资源缓存策略配置
    算术验证
    JPA学习
    Spring中AOP实现
    转:Spring中事物管理
    使用docker发布spring cloud应用
    综合使用spring cloud技术实现微服务应用
  • 原文地址:https://www.cnblogs.com/yizhidaozuihou/p/12829907.html
Copyright © 2011-2022 走看看