1. <?php
  2. /**
  3. * 基于redis的分布式锁
  4. *
  5. * 参考开源代码:
  6. * http://nleach.com/post/31299575840/redis-mutex-in-php
  7. *
  8. * https://gist.github.com/nickyleach/3694555
  9. */
  10. pc_base::load_sys_class('cache_redis', '', 0);
  11.  
  12. class dist_key_redis {
  13.  
  14. //锁的超时时间
  15. const TIMEOUT = 20;
  16.  
  17. const SLEEP = 100000;
  18.  
  19. /**
  20. * Stores the expire time of the currently held lock
  21. * 当前锁的过期时间
  22. * @var int
  23. */
  24. protected static $expire;
  25.  
  26. public static function getRedis()
  27. {
  28. return new cache_redis();
  29. }
  30.  
  31. /**
  32. * Gets a lock or waits for it to become available
  33. * 获得锁,如果锁被占用,阻塞,直到获得锁或者超时
  34. *
  35. * 如果$timeout参数为0,则立即返回锁。
  36. *
  37. * @param string $key
  38. * @param int $timeout Time to wait for the key (seconds)
  39. * @return boolean 成功,true;失败,false
  40. */
  41. public static function lock($key, $timeout = null){
  42. if(!$key)
  43. {
  44. return false;
  45. }
  46.  
  47. $start = time();
  48.  
  49. $redis = self::getRedis();
  50.  
  51. do{
  52. self::$expire = self::timeout();
  53.  
  54. if($acquired = ($redis->setnx("Lock:{$key}", self::$expire)))
  55. {
  56. break;
  57. }
  58.  
  59. if($acquired = (self::recover($key)))
  60. {
  61. break;
  62. }
  63. if($timeout === 0)
  64. {
  65. //如果超时时间为0,即为
  66. break;
  67. }
  68.  
  69. usleep(self::SLEEP);
  70.  
  71. } while(!is_numeric($timeout) || time() < $start + $timeout);
  72.  
  73. if(!$acquired)
  74. {
  75. //超时
  76. return false;
  77. }
  78.  
  79. return true;
  80. }
  81.  
  82. /**
  83. * Releases the lock
  84. * 释放锁
  85. * @param mixed $key Item to lock
  86. * @throws LockException If the key is invalid
  87. */
  88. public static function release($key){
  89. if(!$key)
  90. {
  91. return false;
  92. }
  93.  
  94. $redis = self::getRedis();
  95.  
  96. // Only release the lock if it hasn't expired
  97. if(self::$expire > time())
  98. {
  99. $redis->del("Lock:{$key}");
  100. }
  101. }
  102.  
  103. /**
  104. * Generates an expire time based on the current time
  105. * @return int timeout
  106. */
  107. protected static function timeout(){
  108. return (int) (time() + self::TIMEOUT + 1);
  109. }
  110.  
  111. /**
  112. * Recover an abandoned lock
  113. * @param mixed $key Item to lock
  114. * @return bool Was the lock acquired?
  115. */
  116. protected static function recover($key){
  117.  
  118. $redis = self::getRedis();
  119.  
  120. if(($lockTimeout = $redis->get("Lock:{$key}")) > time())
  121. {
  122. //锁还没有过期
  123. return false;
  124. }
  125.  
  126. $timeout = self::timeout();
  127. $currentTimeout = $redis->getset("Lock:{$key}", $timeout);
  128.  
  129. if($currentTimeout != $lockTimeout)
  130. {
  131. return false;
  132. }
  133.  
  134. self::$expire = $timeout;
  135. return true;
  136. }
  137. }
  138.  
  139. ?>

基于redis的分布式锁的更多相关文章

  1. 基于redis 实现分布式锁的方案

    在电商项目中,经常有秒杀这样的活动促销,在并发访问下,很容易出现上述问题.如果在库存操作上,加锁就可以避免库存卖超的问题.分布式锁使分布式系统之间同步访问共享资源的一种方式 基于redis实现分布式锁 ...

  2. 基于Redis的分布式锁真的安全吗?

    说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...

  3. 基于 Redis 的分布式锁

    前言 分布式锁在分布式应用中应用广泛,想要搞懂一个新事物首先得了解它的由来,这样才能更加的理解甚至可以举一反三. 首先谈到分布式锁自然也就联想到分布式应用. 在我们将应用拆分为分布式应用之前的单机系统 ...

  4. 基于redis的分布式锁(转)

    基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...

  5. 基于redis的分布式锁实现

    1.分布式锁介绍 在计算机系统中,锁作为一种控制并发的机制无处不在. 单机环境下,操作系统能够在进程或线程之间通过本地的锁来控制并发程序的行为.而在如今的大型复杂系统中,通常采用的是分布式架构提供服务 ...

  6. 基于redis的分布式锁(不适合用于生产环境)

    基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...

  7. 基于 redis 的分布式锁实现 Distributed locks with Redis debug 排查错误

    小结: 1. 锁的实现方式,按照应用的实现架构,可能会有以下几种类型: 如果处理程序是单进程多线程的,在 python下,就可以使用 threading 模块的 Lock 对象来限制对共享变量的同步访 ...

  8. 转载:基于Redis实现分布式锁

    转载:基于Redis实现分布式锁  ,出处: http://blog.csdn.net/ugg/article/details/41894947 背景在很多互联网产品应用中,有些场景需要加锁处理,比如 ...

  9. redis系列:基于redis的分布式锁

    一.介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分为两部分,一个是单机环境, ...

随机推荐

  1. poj1236 强连通

    题意:有 n 个学校每个学校可以将自己的软件共享给其他一些学校,首先,询问至少将软件派发给多少学校能够使软件传播到所有学校,其次,询问添加多少学校共享关系可以使所有学校的软件能够相互传达. 首先,第一 ...

  2. poj1611 带权并查集

    题意:病毒蔓延,现在有 n 个人,其中 0 号被认为可能感染,然后给出多个社交圈,如果某个社交圈里有人被认为可能被感染,那么所有这个社交圈里的人都被认为可能被感染,现在问有多少人可能被感染. 带权并查 ...

  3. [POI 2008][BZOJ 1132]Tro

    这题我真是无能为力了 这题的做法还是挺简单的 枚举左下角的点做为原点,把其余点按极角排序    PS.是作为原点,如枚举到 k 时,对于所有 p[i] (包括p[k]) p[i]-=p[k] (此处为 ...

  4. Netty系列之Netty可靠性分析

      作者 李林锋 发布于 2014年6月19日 | 29 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件分享 稍后阅读 我的阅读清单   1. 背景 1.1. 宕机的代价 1.1. ...

  5. Redis 源码解析

    http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness- ...

  6. C++中智能指针的设计和使用

    转载请标明出处,原文地址:http://blog.csdn.net/hackbuteer1/article/details/7561235 智能指针(smart pointer)是存储指向动态分配(堆 ...

  7. C# 数组,ArrayList与List对象的区别

    在C#中,当我们想要存储一组对象的时候,就会想到用数组,ArrayList,List这三个对象了.那么这三者到底有什么样的区别呢? 我们先来了解一下数组,因为数组在C#中是最早出现的. 数组 数组有很 ...

  8. JSP 相关试题(五)

    Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE MicrosoftInternetExplorer4 /* Style Definiti ...

  9. python str()与repr()

    相同点: 将任意值转为字符串 不同点: str()致力于生成一个对象的可读性好的字符串表示,它的返回结果通常无法用于eval()求值,但很适合用于print语句输出 repr()出来的值是给pytho ...

  10. 创建对象的最好方式&最好的继承机制(代码实例)

    /* 创建对象的最好方式:混合的构造函数/原型方式, *用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法) */ function People(sname){ this.nam ...