云服务器 199 / 年,新老同享,开发者力荐特惠渠道
阿里云推广

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

发表评论

电子邮件地址不会被公开。 必填项已用*标注