servers=$servers;$this->retryDelay=$retryDelay;$this->retryCount=$retryCount;$this->quorum=min(count($servers),(count($servers)/2+1));返回$这个;}privatefunctiongetTime(){returnmicrotime(true)*1000;}publicfunctionlock($resource,$ttl){$this->initInstances();$token=uniqid();$retry=$this->retryCount;做{$n=0;$startTime=$this->getTime();foreach($this->instancesas$instance){如果($this->lockInstance($instance,$resource,$token,$ttl)){$n++;$drift=($ttl*$this->clockDriftFactor)+2;$validityTime=$ttl-($this->getTime()-$startTime)-$drift;如果($n>=$this->quorum&&$validityTime>0){return['validity'=>$validityTime,'resource'=>$resource,'token'=>$token];}else{foreach($this->instancesas$instance){$this->unlockInstance($instance,$resource,$token);$delay=mt_rand(floor($this->retryDelay/2),$this->retryDelay);usleep($延迟*1000);$重试--;}while($retry>0);返回假;}publicfunctionunlock(array$lock){$this->initInstances();$resource=$lock['资源'];$token=$lock['token'];foreach($this->instancesas$instance){$this->unlockInstance($instance,$resource,$token);}}privatefunctioninitInstances(){if(empty($this->instances)){foreach($this->serversas$server){list($host,$port,$timeout)=$server;$redis=new\Redis();$redis->connect($host,$port,$timeout);$this->实例[]=$redis;}}}私有函数lockInstance($instance,$resource,$token,$ttl){return$instance->set($resource,$token,['NX','PX'=>$ttl]);}privatefunctionunlockInstance($instance,$resource,$token){$script='ifredis.call("GET",KEYS[1])==ARGV[1]thenreturnredis.call("DEL",KEYS[1])否则返回0结束';返回$instance->eval($script,[$resource,$token],1);}}使用方法/*/usr/bin/php-ddisplay_error/app/cli.phplocalDemo.redlock*/publicfunctionredlock(){$servers=[['192.168.21.16',6379,0.01]];$redlock=$this->get(SERVICE_REDLOCK)->init($servers);$lock=$redlock->lock('resource_name',1000);打印_r($锁);$redlock->unlock($lock);}
