<?phpclass 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: