php redis 分布式锁

1.redis 分布式锁 (RedisLuckService) 


<?php

namespace App\Models\service;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Log;

class  RedisLuckService
{
    const LUCK_SUCCESS = "OK";
    const IF_NOT_EXISTS = "NX";
    const MILLISECOND_EXPIRE_TIME = "EX";
    const EXPIRE_TIME = 50; //50秒


    /**
     * 加锁
     * @param  $key
     * @param  $uid
     * @param  $expire_time
     * @return bool
     */
    public function lock($key,$uid,$expire_time= '')
    {
        if(empty($expire_time)){
            $expire_time = self::EXPIRE_TIME;
        }
        $result = Redis::set($key,$uid,self::MILLISECOND_EXPIRE_TIME,$expire_time,self::IF_NOT_EXISTS);
        if($result == self::LUCK_SUCCESS){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 释放锁
     * @param  $key
     * @param  $uid
     * @return bool
     */

    public function unlock( $key,  $uid)
    {
        $lua =<<<LUA_SCRIPT
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end
LUA_SCRIPT;
        $result = Redis::eval($lua,1,$key,$uid);
        return $result;
    }
}

 2.模拟并发数据

function redisLuck()
    {
        $redisLuck = new RedisLuckService();
        $uid = $this->userGroup[array_rand($this->userGroup, 1)];
        $key = 'redisLuck';
        try {
            if (!$redisLuck->lock($key, $uid, 4)) {
                $this->setLogs("当前业务繁忙,请稍后==>" . time());
                return "当前业务繁忙,请稍后";
            } else {
                $shopInfo = $this->getShopInfo(1);
                if ($shopInfo->number > 0) {
                    DB::beginTransaction();
                    $this->updateShopInfo($shopInfo->id);
                    $this->addSeckillLog($uid, $shopInfo->id);
                    Db::commit();
                    $this->setLogs("{$uid}抢购成功");
                } else {
                    $this->setLogs("库存不足");
                }

                $redisLuck->unlock($key, $uid);
                $this->setLogs("{$uid}锁已经释放");
            }
        } catch (\Exception $exception) {
            $redisLuck->unlock($key, $uid);
            $this->setLogs("异常:" . $exception->getMessage());
        }
    }

3.采用 ab 测试对接口模拟

ab -n 1000 -c 900 http://域名/seckill/redisLuck

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值