记录一下在用的实战获取redis锁的代码文件。
<?php
class RedisLock
{
private $redis;
protected $lockId;
public function __construct(string $host = '127.0.0.1', int $port = 6379, string $auth = null, int $db = 0) {
$redis = new Redis();
$redis->connect($host, $port);
$auth && $redis->auth($auth);
$redis->select($db);
$this->redis = $redis;
}
public function lock($name = 'lock', $exp = 10, $retry = 10, $sleep = 1000000)
{
$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";
usleep($sleep);
}
return $result;
}
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);
}
}
测试代码:
<?php
ini_set('display_errors', 'on');
error_reporting(E_ALL);
require_once("RedisLock.php");
$obj = new RedisLock('redis');
if ($obj->lock($name = 'lock_1_test')) {
echo "执行加锁成功,等待解锁操作...\n";
sleep(5);
echo "-------------------------\n";
$unlockRes = $obj->unlock($name);
if ($unlockRes) {
echo "{$name}, 解锁成功...\n";
}
}