-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathPCodis.php
127 lines (105 loc) · 3.08 KB
/
PCodis.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?php
require 'ZookeeperClient.php' ;
class PCodis
{
private static $_zkConnector ;
private static $_proxyName ;
private static $_proxyNum ;
private static $_codisInstance ;
/**
* @param [string] $address [e.g. "host1:2181,host2:2181"]
* @return [Object ZookeeperClient]
*/
private function _getZkConnector($address)
{
if(self::$_zkConnector !== null ){
return self::$_zkConnector ;
}else{
return self::$_zkConnector = new ZookeeperClient($address) ;
}
}
private static function _setProxyName($proxyName){
self::$_proxyName = $proxyName ;
}
public static function getProxyName(){
return self::$_proxyName ;
}
private static function _setProxyNum($proxyNum){
self::$_proxyNum = $proxyNum ;
}
public static function getProxyNum(){
return self::$_proxyNum ;
}
public static function getCodisInstance($address, $proxyPath, $retryTime=1){
if(!self::$_codisInstance){
$redis = new Redis() ;
//until get a avalible proxy node
$proxyNum = 0 ;
do{
$proxy = self::selectProxy($address, $proxyPath) ;
$proxyNum++ ;
$addr = explode(':', $proxy) ;
$connector = $redis->connect($addr[0], $addr[1]) ;
if(!$connector){
$i = 0 ;
//retry
while($i < $retryTime){
$connector = $redis->connect($addr[0], $addr[1]) ;
$i++ ;
if($connector){
self::$_codisInstance = $redis ;
break ;
}
}
//upto retry maxtime,delete the proxy and then get a new proxy
if($i == $retryTime){
//delete
self::deleteProxy($address, $proxyPath, self::getProxyName()) ;
}
}else{
self::$_codisInstance = $redis ;
break ;
}
}while(!self::$_codisInstance && $proxyNum<=self::getProxyNum()) ;
}
return self::$_codisInstance ;
}
/**
* Get One CodisProxy Address
* @param [string] $address [description]
* @param [string] $proxyPath [description]
* @return [string] [CodisProxyAddr, e.g. "127.0.0.1:19000"]
*/
public static function selectProxy($address, $proxyPath)
{
if(substr($proxyPath, -1) == '/'){ //if the last char is "/" then delete it
$proxyPath = substr($proxyPath, 0, -1) ;
}
$proxyNodes = self::_getZkConnector($address)->getChildren($proxyPath) ;
if(is_array($proxyNodes)){
$proxyNum = count($proxyNodes) ;
$proxyName = $proxyNodes[rand(0, $proxyNum-1)] ;
$proxyStr = self::_getZkConnector($address)->get($proxyPath.'/'.$proxyName) ;
if(strlen($proxyStr)>0 && $proxyInfo = json_decode($proxyStr, true)){
self::_setProxyName($proxyName) ;
self::_setProxyNum($proxyNum) ;
return $proxyInfo['addr'] ;
}
}
return '' ;
}
/**
* Remove the Node
* @param [string] $address [description]
* @param [string] $proxyPath [description]
* @param [string] $proxyName [description]
* @return [type] [description]
*/
public static function deleteProxy($address, $proxyPath, $proxyName)
{
if(substr($proxyPath, -1) == '/'){ //if the last char is "/" then delete it
$proxyPath = substr($proxyPath, 0, -1) ;
}
return self::_getZkConnector($address)->removeNode($proxyPath.'/'.$proxyName) ;
}
}