ClusterTopClient.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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());
  32. if($currentDate - ClusterTopClient::$syncDate > $syncDuration * 60){
  33. $httpdns = new HttpdnsGetRequest;
  34. ClusterTopClient::$dnsconfig = json_decode(parent::execute($httpdns,null,$bestUrl)->result);
  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. $currentEnv = $this->getEnvByApiName($apiname,$session);
  58. $vip = $this->getVipByEnv($url,$currentEnv);
  59. if($vip)
  60. return $vip;
  61. return $url;
  62. }
  63. private function getVipByEnv($comUrl,$currentEnv){
  64. $urlSchema = parse_url($comUrl);
  65. if(!$urlSchema)
  66. return null;
  67. if(!ClusterTopClient::$dnsconfig['env'])
  68. return null;
  69. if(!array_key_exists($currentEnv,ClusterTopClient::$dnsconfig['env']))
  70. return null;
  71. $hostList = ClusterTopClient::$dnsconfig['env'][$currentEnv];
  72. if(!$hostList)
  73. return null ;
  74. $vipList = null;
  75. foreach ($hostList as $key => $value) {
  76. if(strcmp($key,$urlSchema['host']) == 0 && strcmp($value['proto'],$urlSchema['scheme']) == 0){
  77. $vipList = $value;
  78. break;
  79. }
  80. }
  81. $vip = $this->getRandomWeightElement($vipList['vip']);
  82. if($vip){
  83. return $urlSchema['scheme']."://".$vip.$urlSchema['path'];
  84. }
  85. return null;
  86. }
  87. private function getEnvByApiName($apiName,$session=""){
  88. $apiCfgArray = ClusterTopClient::$dnsconfig['api'];
  89. if($apiCfgArray){
  90. if(array_key_exists($apiName,$apiCfgArray)){
  91. $apiCfg = $apiCfgArray[$apiName];
  92. $userFlag = $apiCfg['user'];
  93. $flag = $this->getUserFlag($session);
  94. if($userFlag && $this->getUserFlag($session)){
  95. return $this->getEnvBySessionFlag($userFlag,$flag);
  96. }else{
  97. return $this->getRandomWeightElement($apiCfg['rule']);
  98. }
  99. }
  100. }
  101. return $this->getDeafultEnv();
  102. }
  103. private function getUserFlag($session){
  104. if($session && strlen($session) > 5){
  105. if($session[0] == '6' || $session[0] == '7'){
  106. return $session[strlen($session) -1];
  107. }else if($session[0] == '5' || $session[0] == '8'){
  108. return $session[5];
  109. }
  110. }
  111. return null;
  112. }
  113. private function getEnvBySessionFlag($targetConfig,$flag){
  114. if($flag)
  115. return null;
  116. $userArry = $this->dnsconfig['user'];
  117. $cfgArry = $userConf[$targetConfig];
  118. var_dump($cfgArry);
  119. }
  120. private function getRandomWeightElement($elements){
  121. $totalWeight = 0;
  122. if($elements){
  123. foreach ($elements as $ele) {
  124. $weight = $this->getElementWeight($ele);
  125. $r = $this->randomFloat() * ($weight + $totalWeight);
  126. if($r >= $totalWeight){
  127. $selected = $ele;
  128. }
  129. $totalWeight += $weight;
  130. }
  131. if($selected){
  132. return $this->getElementValue($selected);
  133. }
  134. }
  135. return null;
  136. }
  137. private function getElementWeight($ele){
  138. $params = explode('|', $ele);
  139. return floatval($params[1]);
  140. }
  141. private function getElementValue($ele){
  142. $params = explode('|', $ele);
  143. return $params[0];
  144. }
  145. private function getDeafultEnv(){
  146. return ClusterTopClient::$dnsconfig['config']['def_env'];
  147. }
  148. private static function startsWith($haystack, $needle) {
  149. return $needle === "" || strpos($haystack, $needle) === 0;
  150. }
  151. private function object_to_array($obj)
  152. {
  153. $_arr= is_object($obj) ? get_object_vars($obj) : $obj;
  154. foreach($_arr as $key=> $val)
  155. {
  156. $val= (is_array($val) || is_object($val))? $this->object_to_array($val) : $val;
  157. $arr[$key] = $val;
  158. }
  159. return$arr;
  160. }
  161. private function randomFloat($min = 0, $max = 1) { return $min + mt_rand() / mt_getrandmax() * ($max - $min); }
  162. }
  163. ?>