dubbo-php-framework的服務註冊zookeeper過程解析(一)
阿新 • • 發佈:2018-12-10
我們在分析BaseServer的onManagerStart回撥函式時,看到有呼叫Provider註冊到zookeeper的過程,這篇我們詳細解析下這個過程。
//app啟動後向zookeeper註冊服務資訊 FSOFRegistry::instance()->setParams($this->processName, $this->config, $this->port, $this->serverProviders, $this->start_without_registry); FSOFRegistry::instance()->registerZk();
//註冊單列類 class FSOFRegistry { //設定zookeeper的日誌檔案及日誌級別(1.error; 2.warn; 3.info; 4.debug) const ZOOKEEPER_LOG_NO = 0; const ZOOKEEPER_LOG_ERROR = 1; const ZOOKEEPER_LOG_WARN = 2; const ZOOKEEPER_LOG_INFO = 3; const ZOOKEEPER_LOG_DEBUG = 4; protected $appName;//應用名稱 protected $port;//應用監聽埠資訊 protected $config;//配置資訊 protected $serverProviders;//服務介面資訊 protected $localIp = '127.0.0.1'; protected $ephemeral = false; //zookeeper相關 protected $zkService = null;//zk service protected $fsofUrlList = array();//要註冊到zk的資訊的列表 protected $start_without_registry;//p2p模式 private static $_instance;//本例項資訊,這裡使用了單列模式 private $logger;//日誌元件 //單列模式建立例項 public static function instance() { if (empty(FSOFRegistry::$_instance)) { FSOFRegistry::$_instance = new FSOFRegistry(); } return FSOFRegistry::$_instance; } public function __construct() { $this->logger = \Logger::getLogger(__CLASS__);//初始化日誌元件 } //BaseServer側呼叫這個函式設定相關屬性資訊,這裡屬性資料已經在類的初始化處解釋過,這裡不重複解釋。 public function setParams($appName, $appConfig, $port, $serverProviders, $registry = true) { $this->logger->info("serverProviders:".json_encode($serverProviders)); $this->appName = $appName; $this->port = $port; $this->config = $appConfig; $this->serverProviders = $serverProviders; $this->start_without_registry = $registry; try { //獲取Provider服務所在的機器 $this->localIp = FSOFSystemUtil::getServiceIP(); } catch (\Exception $e) { $this->logger->error('The server network configuration errors',$e); //當獲取IP失敗時,禁止往zk註冊 $this->start_without_registry = true; } }
//註冊到zookeeper public function registerZk() { if(!$this->start_without_registry)//非p2p模式,服務啟動時,需要註冊流程 { try { $this->logger->info("init zk start..."); $this->ServiceSerialize();//生成service urls $this->createZookeeperService();//建立zk service $this->setZkLog();//設定日誌元件資訊 if (!$this->ephemeral)//這個引數按意思是標記是否是短暫註冊,但全篇都是false。 { //靜態註冊模式 $this->registerServiceToZk();//呼叫zk的介面,註冊到zk $this->inventZkService();//登出zk服務 } //連線成功後,通過注入watcherCallFunc函式進行註冊 $this->logger->info("init zk end..."); } catch (\Exception $e) { $this->logger->error($e->getMessage(),$e); } } }
//生成要註冊到zk的服務資訊
protected function ServiceSerialize()
{
try
{
unset($this->fsofUrlList);//清理資訊
if (!empty($this->serverProviders))//服務資訊不為空
{
if ($this->ephemeral)//短暫的
{
//註冊時間
//$this->config["service_properties"]["timestamp"] = (int)(microtime(true) * 1000);
$this->config["service_properties"]["dynamic"] = "true";
}
else//長久的,按邏輯,流程會走這裡。
{
$this->config["service_properties"]["dynamic"] = "false";
}
$services = $this->serverProviders;
foreach ($services as $interface => $serviceInfo)
{
//合併全域性配置
if (isset($this->config["service_properties"]))
{
//介面配置優先順序高於全域性配置,所以$serviceInfo放後面
$serviceInfo = array_merge($this->config["service_properties"], $serviceInfo);
}
//不用上報的資訊去掉
unset($serviceInfo['service']);
unset($serviceInfo['p2p_mode']);
if (empty($serviceInfo["version"]))
{
$serviceInfo['version'] = FSOFConstants::FSOF_SERVICE_VERSION_DEFAULT;
}
//與dubbo相容處理
$serviceInfo['interface'] = $interface;//dubbo_admin需要使用
//序列化方式
$serviceInfo['serialization']= "fastjson";
ksort($serviceInfo);//引數排序,與dubbo相容
//要註冊到zk的url資訊組成部分
$urlPara = array(
'scheme' => 'dubbo',
'host' => $this->localIp,
'port' => $this->port,
'path' => '/' . $interface,
//http_build_query會進行urlencode導致query引數被多編碼一次,使用urldecode抵消
'query' => urldecode(http_build_query($serviceInfo)),
);
$this->logger->debug("serviceInfo:" . json_encode($serviceInfo) . "|urlPara:" . json_encode($urlPara));
try
{
$fsofUrl = new FSOFUrl($urlPara);//按規則拼接dubbo的url協議
}
catch (\Exception $e)
{
$this->logger->error('init url failed|app:' . $this->appName . '|urlPara:' . json_encode($urlPara));
}
$this->fsofUrlList[] = $fsofUrl;
}
}
}
catch(\Exception $e)
{
$errMsg = $e->getMessage();
$this->logger->error('ServiceSerialize:'.$errMsg, $e);
}
}