1. 程式人生 > >dubbo-php-framework的客戶端api解析(二)

dubbo-php-framework的客戶端api解析(二)

這篇我們開始解析ProxyFactory的流程,這個類重點完成了客戶端生成代理的流程,其路徑為dubbo-php-framework-master/consumer/proxy/ProxyFactory.php,我們接著dubbo-php-framework的客戶端api解析(一)中的呼叫進入流程。

//設定配置資訊
public static function setConsumerConfig($configData, $consumerConfigFile, $initSettings)
	{
        self::$logger = \Logger::getLogger(__CLASS__);

		//App名字
		self::$appName = $initSettings['app_name'];

		//獲取app載入配置檔案;輸出日誌方便問題定位
		self::$appConfigFile = $consumerConfigFile;

		//是否開啟p2p模式, p2p模式下, 將使用[consumer_services]下的資訊進行路由
		if(isset($configData['consumer_config']['p2p_mode']) && $configData['consumer_config']['p2p_mode'])
		{
			self::$p2pMode = $configData['consumer_config']['p2p_mode'];
		}

        //consumer側group資訊
		if (isset($configData['consumer_config']['group']))
		{
			self::$appGroup = $configData['consumer_config']['group'];
		}
        
        //consumer端的版本資訊
		if(isset($configData['consumer_config']['version']))
		{
			self::$appVersion = $configData['consumer_config']['version'];
		}

        //consumer端直接呼叫的service資訊
		if(isset($configData['consumer_services']))
		{
			self::$serviceConsumers = $configData['consumer_services'];
		}
	}
//獲取Proxy例項資訊,其中consumerInterface為要呼叫的服務地址資訊
public static function getInstance($consumerInterface, $ioTimeOut = 3)
    {
    	$ret = NULL;
        $route = '';
        $addressList = 'null';

		//app級組和版本資訊
		$group = self::$appGroup;
		$versionList = self::$appVersion;

        //判斷服務地址資訊是否已經存在,這個結合上面程式碼可以看出,這種情況為p2p模式。
		if (array_key_exists($consumerInterface, self::$serviceConsumers))
		{
            $serviceProperty = self::$serviceConsumers[$consumerInterface];
			if(isset($serviceProperty['group'])) //解析組別資訊
			{
				$group = $serviceProperty['group'];
			}
			if(isset($serviceProperty['version']))//解析版本號資訊
			{
				$versionList = $serviceProperty['version'];
			}
		}

		try
		{

			//依據配置權重選取版本號,後續解析
			$version = FSOFCommonUtil::getVersionByWeight($versionList);

			//p2p模式
			if (self::$p2pMode)
			{
				$ret = self::getInstanceByP2P($consumerInterface, $ioTimeOut, $version, $group);
				$route = 'p2p';
			}

			if (empty($ret))
			{
				//registry 模式
				$ret = self::getInstancByRedis($consumerInterface, $ioTimeOut, $version, $group);
				$route = 'auto registry';
			}

			if (empty($ret))//為獲取到相應的例項資訊
			{
				$errMsg = "current_address:".FSOFSystemUtil::getLocalIP()."|".$consumerInterface;
                throw new \Exception($errMsg);
			}
			else
			{
                $addressList = $ret->getAddressStr();//獲取地址資訊,這裡主要用來列印日誌資訊
			}

            self::$logger->debug('consumer_app:'.self::$appName.'|app_config_file:'.self::$appConfigFile.
                '|version:'.$version.'|group:'.$group.'|provider_service:'.$consumerInterface.'|route:'.$route.'|addr_list:'.$addressList.'|timeout:'.$ioTimeOut);
        }
        catch (\Exception $e)
        {
            self::$logger->error('consumer_app:'.self::$appName.'|app_config_file:'.self::$appConfigFile.
                '|version:'.$version.'|group:'.$group.'|provider_service:'.$consumerInterface.'|errmsg:'. $e->getMessage().'|exceptionmsg:'.$e);
        }
    	return $ret;
    }
//use p2p mode
    private static function getInstanceByP2P($service, $ioTimeOut, $version, $group)
    {
        $ret = NULL;
        if(array_key_exists($service, self::$serviceConsumers))
        {
            $serviceProperty = self::$serviceConsumers[$service];
			if (isset($serviceProperty['url']))
			{
				$ret = Proxy::newProxyInstance($service, self::$appName, $group);

				//設定io超時時間
				$ret->setIOTimeOut($ioTimeOut);

				//設定所用服務的ip地址列表
				$serviceAddr = explode(",",$serviceProperty['url']);
				$serviceUrls = array();
				foreach ($serviceAddr as $index => $addr)
				{
					$tmpUrl = $addr.'/'."{$service}?version={$version}&group={$group}";
					$serviceUrls[] = new FSOFUrl($tmpUrl);
				}
				$ret->setAddress($serviceUrls);
			}
			else
			{
                self::$logger->warn(self::$appName.'.consumer not exist url');
			}
        }
        else 
        {
            self::$logger->warn('service not found on p2p|consumer_app:'.self::$appName.'|provider_service:'.$service);
        }
        
        return $ret;         
    }