正文
class RedisTool { const LOCK_SUCCESS = 'OK'; const IF_NOT_EXIST = 'NX'; const MILLISECONDS_EXPIRE_TIME = 'PX'; const RELEASE_SUCCESS = 1; /**
* 尝试获取锁
* @param $redis redis客户端
* @param $key 锁
* @param $requestId 请求id
* @param $expireTime 过期时间
* @return bool 是否获取成功
*/
public static function tryGetLock($redis, $key, $requestId, $expireTime) {
$result = $redis->set( $key, $requestId, self::MILLISECONDS_EXPIRE_TIME, $expireTime, self::IF_NOT_EXIST ); return self::LOCK_SUCCESS === (string)$result;
}
}
定义一些Redis的操作符作为常量, 加锁的代码其实很简单, 一行代码即可. 简单解释下这个set方法的五个参数:
-
第一个key是锁的名字, 这个由具体业务逻辑控制, 保证唯一即可
-
第二个是请求ID, 可能不好理解. 这样做的目的主要是为了保证加解锁的唯一性. 这样我们就可以知道该锁是哪个客户端加的.
-
第三个参数是一个标识符, 标识时间戳以毫秒为最小单位
-
具体的过期时间
-
这个参数是NX, 表示当key不存在时我们才进行set操作
PS. 请求的唯一性ID生成方式很多, 可以参考下这个chronos. 该库涉及到Thrift的RPC调用, 可能上手会比较麻烦, 下回给出一个简单的PHP实现.
简单解释下上面的那段代码, 设置NX保证了只能有一个客户端获取到锁, 满足互斥性; 加入了过期时间, 保证在客户端崩溃后不会造成死锁; 请求ID的作用是用来标识客户端, 这样客户端在解锁的时候可以进行校验是否同一个客户端.