You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
5.5 KiB
PHTML

5 years ago
<?php
class ClusterTopClient extends TopClient {
private static $dnsconfig;
private static $syncDate = 0;
private static $applicationVar ;
private static $cfgDuration = 10;
public function __construct($appkey = "",$secretKey = ""){
ClusterTopClient::$applicationVar = new ApplicationVar;
$this->appkey = $appkey;
$this->secretKey = $secretKey ;
$saveConfig = ClusterTopClient::$applicationVar->getValue();
if($saveConfig){
$tmpConfig = $saveConfig['dnsconfig'];
ClusterTopClient::$dnsconfig = $this->object_to_array($tmpConfig);
unset($tmpConfig);
ClusterTopClient::$syncDate = $saveConfig['syncDate'];
if(!ClusterTopClient::$syncDate)
ClusterTopClient::$syncDate = 0;
}
}
public function __destruct(){
if(ClusterTopClient::$dnsconfig && ClusterTopClient::$syncDate){
ClusterTopClient::$applicationVar->setValue("dnsconfig",ClusterTopClient::$dnsconfig);
ClusterTopClient::$applicationVar->setValue("syncDate",ClusterTopClient::$syncDate);
ClusterTopClient::$applicationVar->write();
}
}
public function execute($request = null, $session = null,$bestUrl = null){
$currentDate = date('U');
$syncDuration = $this->getDnsConfigSyncDuration();
$bestUrl = $this->getBestVipUrl($this->gatewayUrl,$request->getApiMethodName(),$session);
if($currentDate - ClusterTopClient::$syncDate > $syncDuration * 60){
$httpdns = new HttpdnsGetRequest;
ClusterTopClient::$dnsconfig = json_decode(parent::execute($httpdns,null,$bestUrl)->result,true);
$syncDate = date('U');
ClusterTopClient::$syncDate = $syncDate ;
}
return parent::execute($request,$session,$bestUrl);
}
private function getDnsConfigSyncDuration(){
if(ClusterTopClient::$cfgDuration){
return ClusterTopClient::$cfgDuration;
}
if(!ClusterTopClient::$dnsconfig){
return ClusterTopClient::$cfgDuration;
}
$config = json_encode(ClusterTopClient::$dnsconfig);
if(!$config){
return ClusterTopClient::$cfgDuration;
}
$config = ClusterTopClient::$dnsconfig['config'];
$duration = $config['interval'];
ClusterTopClient::$cfgDuration = $duration;
return ClusterTopClient::$cfgDuration;
}
private function getBestVipUrl($url,$apiname = null,$session = null){
$config = ClusterTopClient::$dnsconfig['config'];
$degrade = $config['degrade'];
if(strcmp($degrade,'true') == 0){
return $url;
}
$currentEnv = $this->getEnvByApiName($apiname,$session);
$vip = $this->getVipByEnv($url,$currentEnv);
if($vip)
return $vip;
return $url;
}
private function getVipByEnv($comUrl,$currentEnv){
$urlSchema = parse_url($comUrl);
if(!$urlSchema)
return null;
if(!ClusterTopClient::$dnsconfig['env'])
return null;
if(!array_key_exists($currentEnv,ClusterTopClient::$dnsconfig['env']))
return null;
$hostList = ClusterTopClient::$dnsconfig['env'][$currentEnv];
if(!$hostList)
return null ;
$vipList = null;
foreach ($hostList as $key => $value) {
if(strcmp($key,$urlSchema['host']) == 0 && strcmp($value['proto'],$urlSchema['scheme']) == 0){
$vipList = $value;
break;
}
}
$vip = $this->getRandomWeightElement($vipList['vip']);
if($vip){
return $urlSchema['scheme']."://".$vip.$urlSchema['path'];
}
return null;
}
private function getEnvByApiName($apiName,$session=""){
$apiCfgArray = ClusterTopClient::$dnsconfig['api'];
if($apiCfgArray){
if(array_key_exists($apiName,$apiCfgArray)){
$apiCfg = $apiCfgArray[$apiName];
if(array_key_exists('user',$apiCfg)){
$userFlag = $apiCfg['user'];
$flag = $this->getUserFlag($session);
if($userFlag && $flag ){
return $this->getEnvBySessionFlag($userFlag,$flag);
}else{
return $this->getRandomWeightElement($apiCfg['rule']);
}
}
}
}
return $this->getDeafultEnv();
}
private function getUserFlag($session){
if($session && strlen($session) > 5){
if($session[0] == '6' || $session[0] == '7'){
return $session[strlen($session) -1];
}else if($session[0] == '5' || $session[0] == '8'){
return $session[5];
}
}
return null;
}
private function getEnvBySessionFlag($targetConfig,$flag){
if($flag){
$userConf = ClusterTopClient::$dnsconfig['user'];
$cfgArry = $userConf[$targetConfig];
foreach ($cfgArry as $key => $value) {
if(in_array($flag,$value))
return $key;
}
}else{
return null;
}
}
private function getRandomWeightElement($elements){
$totalWeight = 0;
if($elements){
foreach ($elements as $ele) {
$weight = $this->getElementWeight($ele);
$r = $this->randomFloat() * ($weight + $totalWeight);
if($r >= $totalWeight){
$selected = $ele;
}
$totalWeight += $weight;
}
if($selected){
return $this->getElementValue($selected);
}
}
return null;
}
private function getElementWeight($ele){
$params = explode('|', $ele);
return floatval($params[1]);
}
private function getElementValue($ele){
$params = explode('|', $ele);
return $params[0];
}
private function getDeafultEnv(){
return ClusterTopClient::$dnsconfig['config']['def_env'];
}
private static function startsWith($haystack, $needle) {
return $needle === "" || strpos($haystack, $needle) === 0;
}
private function object_to_array($obj)
{
$_arr= is_object($obj) ? get_object_vars($obj) : $obj;
foreach($_arr as $key=> $val)
{
$val= (is_array($val) || is_object($val))? $this->object_to_array($val) : $val;
$arr[$key] = $val;
}
return$arr;
}
private function randomFloat($min = 0, $max = 1) { return $min + mt_rand() / mt_getrandmax() * ($max - $min); }
}
?>