<? PHP/*** redis-based Distributed Lock ** reference open source code: * 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 {// lock timeout value const timeout = 20; const sleep = 100000; /*** stores the expire time of the currently held lock * expiration time of the Current lock * @ var int */protected static $ expire; public static function getredis (){ Return new cache_redis ();}/*** gets a lock or waits for it to become available * get the lock. If the lock is occupied, it is blocked, wait until the lock is obtained or times out. ** if the $ timeout parameter is 0, the lock is returned immediately. ** @ Param string $ key * @ Param int $ timeout time to wait for the key (seconds) * @ return Boolean success, true; failure, 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) {// If the timeout value is 0, that is, break;} usleep (SELF: Sleep);} while (! Is_numeric ($ timeout) | time () <$ start + $ timeout); If (! $ Acquired) {// return false;} return true ;} /*** releases the lock * release 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 when the lock has not expired;} $ timeout = self: timeout (); $ currenttimeout = $ redis-> GetSet ("lock: {$ key}", $ timeout); if ($ currenttimeout! = $ Locktimeout) {return false;} self: $ expire = $ timeout; return true ;}}?>
Redis-based distributed locks