<?php
class locks{
private $redis;
protected $lockid; // 记录客户端加锁的 ID
public function __construct(){$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$this->redis = $redis;
}
/**
* @param string $name 参数名
* @param int $exp 过期工夫
* @param int $retry 反复次数
* @param int $sleep 等待时间
*/
public function lock($name = 'lock',$exp = 30, $retry = 10 , $sleep = 1){
$result = false;
while ($retry-- >= 0){$value = md5(date("Y-m-d H:i:s"));
$result = $this->redis->set($name , $value , ['NX' , 'EX'=>$exp] );
if ($result) {$this->lockid[$name] = $value;
echo $name.'胜利获取到锁,正在执行' . "\n";
break;
}
echo $name.'加锁失败·· 失常尝试获取锁' ."\n";
sleep($sleep);
}
return $result;
}
/**
* @param $name
* @return mixed
* 删除锁
*/
public function unlock($name){
echo $name.'失常执行解锁···' ."\n";
$lua = "
local key = KEYS[1]
local value = ARGV[1]
if(redis.call('get', key) == value)
then
return redis.call('del', key)
end";
return $this->redis->eval($lua, [$name, $this->lockid[$name]], 1);
}
}
// 申请分布式锁
$obj = new locks();
// 执行实现申请解锁
if($obj->lock($name = "lock_1")){
echo "执行完结,期待 5s 执行解锁操作···"."\n";
sleep(5);
echo "--------------------------"."\n";
$unlockResult = $obj->unlock($name);
if($unlockResult){echo $name.'解锁胜利··' ."\n";}
}
Redis 申请分布式锁的命令,此命令合乎原子性:
/**
* SET:Redis 的 String 指令
* lock_name:锁的名称
* unique_id:锁的惟一校验
* NX:工夫单位
* PX:设置过期工夫
*/
SET lock_name unique_id NX PX expire_time
别离执行,具体执行后果:
<?php
// 申请分布式锁
$obj = new locks();
// 执行实现申请解锁
if($obj->lock($name = "lock_1")){
echo "执行完结,期待 5s 执行解锁操作···"."\n";
sleep(5);
echo "--------------------------"."\n";
$unlockResult = $obj->unlock($name);
if($unlockResult){echo $name.'解锁胜利··' ."\n";}
}
客户端 1:
客户端 2: