ClusterTopClient.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?php
  2. class ClusterTopClient extends TopClient {
  3. private static $dnsconfig;
  4. private static $syncDate = 0;
  5. private static $applicationVar ;
  6. private static $cfgDuration = 10;
  7. public function __construct($appkey = "",$secretKey = ""){
  8. ClusterTopClient::$applicationVar = new ApplicationVar;
  9. $this->appkey = $appkey;
  10. $this->secretKey = $secretKey ;
  11. $saveConfig = ClusterTopClient::$applicationVar->getValue();
  12. if($saveConfig){
  13. $tmpConfig = $saveConfig['dnsconfig'];
  14. ClusterTopClient::$dnsconfig = $this->object_to_array($tmpConfig);
  15. unset($tmpConfig);
  16. ClusterTopClient::$syncDate = $saveConfig['syncDate'];
  17. if(!ClusterTopClient::$syncDate)
  18. ClusterTopClient::$syncDate = 0;
  19. }
  20. }
  21. public function __destruct(){
  22. if(ClusterTopClient::$dnsconfig && ClusterTopClient::$syncDate){
  23. ClusterTopClient::$applicationVar->setValue("dnsconfig",ClusterTopClient::$dnsconfig);
  24. ClusterTopClient::$applicationVar->setValue("syncDate",ClusterTopClient::$syncDate);
  25. ClusterTopClient::$applicationVar->write();
  26. }
  27. }
  28. public function execute($request = null, $session = null,$bestUrl = null){
  29. $currentDate = date('U');
  30. $syncDuration = $this->getDnsConfigSyncDuration();
  31. $bestUrl = $this->getBestVipUrl($this->gatewayUrl,$request->getApiMethodName(),$session);
  32. if($currentDate - ClusterTopClient::$syncDate > $syncDuration * 60){
  33. $httpdns = new HttpdnsGetRequest;
  34. ClusterTopClient::$dnsconfig = json_decode(parent::execute($httpdns,null,$bestUrl)->result,true);
  35. $syncDate = date('U');
  36. ClusterTopClient::$syncDate = $syncDate ;
  37. }
  38. return parent::execute($request,$session,$bestUrl);
  39. }
  40. private function getDnsConfigSyncDuration(){
  41. if(ClusterTopClient::$cfgDuration){
  42. return ClusterTopClient::$cfgDuration;
  43. }
  44. if(!ClusterTopClient::$dnsconfig){
  45. return ClusterTopClient::$cfgDuration;
  46. }
  47. $config = json_encode(ClusterTopClient::$dnsconfig);
  48. if(!$config){
  49. return ClusterTopClient::$cfgDuration;
  50. }
  51. $config = ClusterTopClient::$dnsconfig['config'];
  52. $duration = $config['interval'];
  53. ClusterTopClient::$cfgDuration = $duration;
  54. return ClusterTopClient::$cfgDuration;
  55. }
  56. private function getBestVipUrl($url,$apiname = null,$session = null){
  57. $config = ClusterTopClient::$dnsconfig['config'];
  58. $degrade = $config['degrade'];
  59. if(strcmp($degrade,'true') == 0){
  60. return $url;
  61. }
  62. $currentEnv = $this->getEnvByApiName($apiname,$session);
  63. $vip = $this->getVipByEnv($url,$currentEnv);
  64. if($vip)
  65. return $vip;
  66. return $url;
  67. }
  68. private function getVipByEnv($comUrl,$currentEnv){
  69. $urlSchema = parse_url($comUrl);
  70. if(!$urlSchema)
  71. return null;
  72. if(!ClusterTopClient::$dnsconfig['env'])
  73. return null;
  74. if(!array_key_exists($currentEnv,ClusterTopClient::$dnsconfig['env']))
  75. return null;
  76. $hostList = ClusterTopClient::$dnsconfig['env'][$currentEnv];
  77. if(!$hostList)
  78. return null ;
  79. $vipList = null;
  80. foreach ($hostList as $key => $value) {
  81. if(strcmp($key,$urlSchema['host']) == 0 && strcmp($value['proto'],$urlSchema['scheme']) == 0){
  82. $vipList = $value;
  83. break;
  84. }
  85. }
  86. $vip = $this->getRandomWeightElement($vipList['vip']);
  87. if($vip){
  88. return $urlSchema['scheme']."://".$vip.$urlSchema['path'];
  89. }
  90. return null;
  91. }
  92. private function getEnvByApiName($apiName,$session=""){
  93. $apiCfgArray = ClusterTopClient::$dnsconfig['api'];
  94. if($apiCfgArray){
  95. if(array_key_exists($apiName,$apiCfgArray)){
  96. $apiCfg = $apiCfgArray[$apiName];
  97. if(array_key_exists('user',$apiCfg)){
  98. $userFlag = $apiCfg['user'];
  99. $flag = $this->getUserFlag($session);
  100. if($userFlag && $flag ){
  101. return $this->getEnvBySessionFlag($userFlag,$flag);
  102. }else{
  103. return $this->getRandomWeightElement($apiCfg['rule']);
  104. }
  105. }
  106. }
  107. }
  108. return $this->getDeafultEnv();
  109. }
  110. private function getUserFlag($session){
  111. if($session && strlen($session) > 5){
  112. if($session[0] == '6' || $session[0] == '7'){
  113. return $session[strlen($session) -1];
  114. }else if($session[0] == '5' || $session[0] == '8'){
  115. return $session[5];
  116. }
  117. }
  118. return null;
  119. }
  120. private function getEnvBySessionFlag($targetConfig,$flag){
  121. if($flag){
  122. $userConf = ClusterTopClient::$dnsconfig['user'];
  123. $cfgArry = $userConf[$targetConfig];
  124. foreach ($cfgArry as $key => $value) {
  125. if(in_array($flag,$value))
  126. return $key;
  127. }
  128. }else{
  129. return null;
  130. }
  131. }
  132. private function getRandomWeightElement($elements){
  133. $totalWeight = 0;
  134. if($elements){
  135. foreach ($elements as $ele) {
  136. $weight = $this->getElementWeight($ele);
  137. $r = $this->randomFloat() * ($weight + $totalWeight);
  138. if($r >= $totalWeight){
  139. $selected = $ele;
  140. }
  141. $totalWeight += $weight;
  142. }
  143. if($selected){
  144. return $this->getElementValue($selected);
  145. }
  146. }
  147. return null;
  148. }
  149. private function getElementWeight($ele){
  150. $params = explode('|', $ele);
  151. return floatval($params[1]);
  152. }
  153. private function getElementValue($ele){
  154. $params = explode('|', $ele);
  155. return $params[0];
  156. }
  157. private function getDeafultEnv(){
  158. return ClusterTopClient::$dnsconfig['config']['def_env'];
  159. }
  160. private static function startsWith($haystack, $needle) {
  161. return $needle === "" || strpos($haystack, $needle) === 0;
  162. }
  163. private function object_to_array($obj)
  164. {
  165. $_arr= is_object($obj) ? get_object_vars($obj) : $obj;
  166. foreach($_arr as $key=> $val)
  167. {
  168. $val= (is_array($val) || is_object($val))? $this->object_to_array($val) : $val;
  169. $arr[$key] = $val;
  170. }
  171. return$arr;
  172. }
  173. private function randomFloat($min = 0, $max = 1) { return $min + mt_rand() / mt_getrandmax() * ($max - $min); }
  174. }
  175. ?>