<?php
/**
* 基于redis的分布式锁
*
* 参考开源代码:
* http://nleach.com/post/31299575840/redis-mutex-in-php
*
* https://gist.github.com/nickyleach/3694555
*/
pc_base::load_sys_class('cache_redis', '', 0); class dist_key_redis { //锁的超时时间
const TIMEOUT = 20; const SLEEP = 100000; /**
* Stores the expire time of the currently held lock
* 当前锁的过期时间
* @var int
*/
protected static $expire; public static function getRedis()
{
return new cache_redis();
} /**
* Gets a lock or waits for it to become available
* 获得锁,如果锁被占用,阻塞,直到获得锁或者超时
*
* 如果$timeout参数为0,则立即返回锁。
*
* @param string $key
* @param int $timeout Time to wait for the key (seconds)
* @return boolean 成功,true;失败,false
*/
public static function lock($key, $timeout = null){
if(!$key)
{
return false;
} $start = time(); $redis = self::getRedis(); do{
self::$expire = self::timeout(); if($acquired = ($redis->setnx("Lock:{$key}", self::$expire)))
{
break;
} if($acquired = (self::recover($key)))
{
break;
}
if($timeout === 0)
{
//如果超时时间为0,即为
break;
} usleep(self::SLEEP); } while(!is_numeric($timeout) || time() < $start + $timeout); if(!$acquired)
{
//超时
return false;
} return true;
} /**
* Releases the lock
* 释放锁
* @param mixed $key Item to lock
* @throws LockException If the key is invalid
*/
public static function release($key){
if(!$key)
{
return false;
} $redis = self::getRedis(); // Only release the lock if it hasn't expired
if(self::$expire > time())
{
$redis->del("Lock:{$key}");
}
} /**
* Generates an expire time based on the current time
* @return int timeout
*/
protected static function timeout(){
return (int) (time() + self::TIMEOUT + 1);
} /**
* Recover an abandoned lock
* @param mixed $key Item to lock
* @return bool Was the lock acquired?
*/
protected static function recover($key){ $redis = self::getRedis(); if(($lockTimeout = $redis->get("Lock:{$key}")) > time())
{
//锁还没有过期
return false;
} $timeout = self::timeout();
$currentTimeout = $redis->getset("Lock:{$key}", $timeout); if($currentTimeout != $lockTimeout)
{
return false;
} self::$expire = $timeout;
return true;
}
} ?>

基于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. I’m stuck!(BFS)

    I’m stuck! 给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', 'S', 'T'七个字符中的一个,分别表示如下意思: '#': 任何时候玩家都不能 ...

  2. Fragment用app包还是v4包解析

    转自:http://blog.csdn.net/zc0908/article/details/50721553 1)问题简述 相信很多的朋友在调用Fragment都会遇到下面的情况: 这个时候问题来了 ...

  3. java Pattern

    public class Test{ //匹配替换掉order by之后的字符串 public static void main(String[] args) { Pattern pattern = ...

  4. UMDH

    1. 什么是UMDH UMDH=User Mode dump heap.把进程的堆dump下来.包括堆栈信息.UMDH是WinDbg附带的一个工具. 2. 下载安装 WinDbg.完事后在WinDbg ...

  5. Phython 学习笔记之——类的初步认识

    类是面向对象编程的核心,他扮演相关数据及逻辑容器的角色.他们提供了创建实例对象的蓝图.因为python语言不要求必须以面向对象的方式编程(与JAVA不同),这里简单的举一个例子. 如何定义一个类 cl ...

  6. MySQL中char(36)被认为是GUID导致的BUG及解决方案

    MySQL中char(36)被认为是GUID导致的BUG及解决方案 有时候在使用Toad或在程序中,偶尔会遇到如下的错误: System.FormatException GUID 应包含带 4 个短划 ...

  7. Vs 2013 单步调试 .net framework 中遇到的问题

    为了可以看清.net framework 的的内部机制,进行单步实际是不错的选择啊,   其它的更多设置可以看其它文章,我这里主要讲问题.     然后就会加载PDB,然后就可以单步进入了. 但是 , ...

  8. unity, 查看build版log文件

    http://blog.theknightsofunity.com/accessing-unity-game-logs/

  9. 【Reporting Services 报表开发】— 表达式

    一.常用的SSRS原始函数可以打开文本框的表达式中看到,如图1 图1 如下为SSRS中设计报表时常用的运算函数: 运算符/函数 说明 + 前后位数字则为加法,前后为字符串则为链接符号 - 数值减法 * ...

  10. svn钩子(hooks)

    首先你需要搭建出自己的svn环境出来,并能成功导入导出,并且了解svn,这是看这篇文章的前提.... 出于公司开发部需要svn同步更新服务器代码,需要用到svn钩子(hooks)技术,以前从来没听过, ...