绳锯木断,水滴石穿!
Redis > php使用redis锁限制并发访问类示例(学习记录)

php使用redis锁限制并发访问类示例(学习记录)

2020-09-28 分类:Redis 作者:Agoni 阅读(961)

在学习redis和mysql数据库锁机制的时候,经常让人头痛;
RedisLock.class.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?php
/**
 * Redis锁操作类
 * Date:  2016-06-30
 * Author: fdipzone
 * Ver:  1.0
 *
 * Func:
 * public lock  获取锁
 * public unlock 释放锁
 * private connect 连接
 */

class RedisLock { // class start
 
  private $_config;
  private $_redis;
 
  /**
   * 初始化
   * @param Array $config redis连接设定
   */

  public function __construct($config=array()){
    $this->_config = $config;
    $this->_redis = $this->connect();
  }
 
  /**
   * 获取锁
   * @param String $key  锁标识
   * @param Int   $expire 锁过期时间
   * @return Boolean
   */

  public function lock($key, $expire=5){
    $is_lock = $this->_redis->setnx($key, time()+$expire);
 
    // 不能获取锁
    if(!$is_lock){
 
      // 判断锁是否过期
      $lock_time = $this->_redis->get($key);
 
      // 锁已过期,删除锁,重新获取
      if(time()>$lock_time){
        $this->unlock($key);
        $is_lock = $this->_redis->setnx($key, time()+$expire);
      }
    }
 
    return $is_lock? true : false;
  }
 
  /**
   * 释放锁
   * @param String $key 锁标识
   * @return Boolean
   */

  public function unlock($key){
    return $this->_redis->del($key);
  }
 
  /**
   * 创建redis连接
   * @return Link
   */

  private function connect(){
    try{
      $redis = new Redis();
      $redis->connect($this->_config['host'],$this->_config['port'],$this->_config['timeout'],$this->_config['reserved'],$this->_config['retry_interval']);
      if(empty($this->_config['auth'])){
        $redis->auth($this->_config['auth']);
      }
      $redis->select($this->_config['index']);
    }catch(RedisException $e){
      throw new Exception($e->getMessage());
      return false;
    }
    return $redis;
  }
 
} // class end
 
?>

demo.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
require 'RedisLock.class.php';
 
$config = array(
  'host' => 'localhost',
  'port' => 6379,
  'index' => 0,
  'auth' => '',
  'timeout' => 1,
  'reserved' => NULL,
  'retry_interval' => 100,
);
 
// 创建redislock对象
$oRedisLock = new RedisLock($config);
 
// 定义锁标识
$key = 'mylock';
 
// 获取锁
$is_lock = $oRedisLock->lock($key, 10);
 
if($is_lock){
  echo 'get lock success<br>';
  echo 'do sth..<br>';
  sleep(5);
  echo 'success<br>';
  $oRedisLock->unlock($key);
 
// 获取锁失败
}else{
  echo 'request too frequently<br>';
}
 
?>
1
2
3
4
5
6
7
8
9
10
11
测试方法:
打开两个不同的浏览器,同时在A,B中访问demo.php
如果先访问的会获取到锁
输出
get lock success
do sth..
success
另一个获取锁失败则会输出request too frequently
保证同一时间只有一个访问有效,有效限制并发访问。
为了避免系统突然出错导致死锁,所以在获取锁的时候增加一个过期时间,
如果已超过过期时间,即使是锁定状态都会释放锁,避免死锁导致的问题。

「 有志者自有千计万计,无志者只感千难万难 」

赞(1) 打赏
1

谢谢,共同进步~

支付宝
微信
标签:

上一篇:没有了,已经是最后文章

下一篇:

你可能感兴趣

3 条评论关于"php使用redis锁限制并发访问类示例(学习记录)"

  1. Windows NT Chrome 78.0.3904.108

    666呀

    1. Agoni 本站站主 Windows NT Chrome 86.0.4238.2

      @嗨是的呀

  2. Agoni 本站站主 Windows NT Chrome 86.0.4238.2

    测试评论

博客简介

loading......
姓名:张峰
性别:男
爱好:女
喜欢:旅游,煲剧,写书法,写博客,欢迎一起交流。。。。。。

精彩评论

友情链接

没有人陪你走一辈子,所以你要适应孤独,没有人会帮你一辈子,所以你要奋斗一生!申请交换友链

站点统计

  • 文章总数: 24 篇
  • 草稿数目: 0 篇
  • 分类数目: 10 个
  • 独立页面: 1 个
  • 评论总数: 21 条
  • 链接总数: 3 个
  • 标签总数: 26 个
  • 访问总量: 8082036 次
  • 最近更新: 2021年10月13日
服务热线:
 1995****175

 QQ在线交流

 旺旺在线