php+redis实现分布式锁
同一套代码部署再多台服务器,不同服务器多个线程同时执行某一个方法,让执行动作排序,保证线程安全。
<?php
header("Access-Control-Allow-Origin:*");
header('Access-Control-Allow-Methods:*');
#分布式锁
class RedisLock {
private $redis;
#存储redis对象
/**
* @desc 构造函数
*
* @param $host string | redis主机
* @param $port int | 端口
*/
public function __construct($host,$port=6379,$pass='') {
$this->redis = new Redis();
$this->redis->connect($host,$port);
if(!!$pass){
$this->redis->auth($pass); //密码验证
}
}
/**
* @desc 加锁方法
*
* @param $lockName string | 锁的名字
* @param $timeout int | 锁的过期时间
* @return 成功返回identifier/失败返回false
*/
public function getLock($lockName, $timeout=10) {
$identifier=uniqid();
#获取唯一标识符
$timeout = intval($timeout);
#确保是整数
$end=time()+$timeout;
#循环获取锁
while(time()<$end) {
#查看$lockName是否被上锁,为$lockName设置过期时间,防止死锁
if($this->redis->set($lockName, $identifier, array('nx', 'ex' => $timeout))) {
return $identifier;
}
usleep(0.001);
#停止0.001ms
}
return false;
}
/**
* @desc 释放锁
*
* @param $lockName string | 锁名
* @param $identifier string | 锁的唯一值
*
* @param bool
*/
public function releaseLock($lockName,$identifier) {
// 判断是锁有没有被其他客户端修改
if($this->redis->get($lockName)==$identifier) {
$this->redis->multi();
$this->redis->del($lockName);
#释放锁
$this->redis->exec();
return true;
} else {
return false;
#其他客户端修改了锁,不能删除别人的锁
}
}
}
header("content-type: text/html;charset=utf8;");
$rLock = new RedisLock('127.0.0.1','6379','*******');
$start=time();
$lockName = "lock:12";
$identifier = $rLock->getLock($lockName);
if($identifier===false) {
var_dump($identifier);
exit("失败了");
}
//模拟业务逻辑处理时长开始
sleep(4);
//模拟业务逻辑处理时长结束
$rLock->releaseLock($lockName,$identifier);
$end=time();
echo "this OK<br/>";
echo "执行时间为:".($end-$start);
?>
版权声明:若无特殊注明,本文皆为《菜鸟站长》原创,转载请保留文章出处。
本文链接:php+redis实现分布式锁 - https://wziyi.net/?post=381