基于PHP和ZooKeeper的简单配置管理实现

文章目录

      • 模块的设计
        • 基本架构
        • 工作流程
      • 核心代码实现
        • 代码实现
        • 配置测试

模块的设计

基本架构

配置管理模块是很多分布式系统的基础,它的主要功能是将用户更新的配置信息实时的同步到各个节点的服务上,以便它们近似实时的加载这些配置,典型的架构如下图所示
基于PHP和ZooKeeper的简单配置管理实现_第1张图片

工作流程

  1. 服务启动后,ConfigFetcher模块与ZooKeeper服务通讯,读取znode节点/serviceA/conf中保存的配置数据,并向该znode节点注册一个watcher以监听节点数据的变更。
  2. 用户通过ConfigUpdater动态的变更znode节点/serviceA/conf中的配置数据。
  3. 各个服务受到节点配置数据变动通知,读取新的配置数据,并重新注册watcher以监听下一次变更。

核心代码实现

代码实现

  1. 配置服务Zookeeper客户端核心代码。该类封装了与ZooKeeper服务端交互的基本函数。
 
/**
 * ConfigClient.class.php
 * 配置模块客户端类
 */
class ConfigClient
{
    private $pZk = null;
    private $strConfPath = '';

    public function __construct($host)
    {
		//实例化ZooKeeper客户端类
        $this->pZk = new Zookeeper($host);
        //设置ZooKeeper日志级别
        $this->pZk->setDebugLevel(Zookeeper::LOG_LEVEL_ERROR);
    }

    /**
     * 设置节点路径
     * @param String $strConfPath 节点路径
     */
    public function setConfPath($strConfPath)
    {
        $this->strConfPath = $strConfPath;
    }

    /**
     * 判断节点是否存在
     * @return [type] [description]
     */
    public function checkExist()
    {
        return $this->pZk->exists($this->strConfPath);
    }

    /**
     * 设置配置项
     * @param array $arrConfig 配置数据
     */
    public function setConf($arrConfig)
    {
        if (false === $this->checkExist()) {
            $arrAcl = [
                [
                    'perms' => Zookeeper::PERM_ALL,
                    'scheme' => 'world',
                    'id' => 'anyone'
                ]
            ];
            //当节点不存在是新建节点
            $result = $this->pZk->create($this->strConfPath, null, $arrAcl);
            if ($result === false) {
                throw new Exception("节点创建失败\n");
            }
        }

        $strConf = json_encode($arrConfig);
        //设置配置数据
        $result = $this->pZk->set($this->strConfPath, $strConf);
        if ($result === false) {
            throw new Exception("配置设置失败\n");
        }
        return true;
    }

    /**
     * 获取配置项
     * @return array 配置数据
     */
    public function getConf()
    {
        if (false === $this->checkExist()) {
            throw new Exception("配置信息不存在\n");
        }
        //获取节点配置信息并设置watcher监听节点变更
        $result = $this->pZk->get($this->strConfPath, [$this, 'watcher']);
        return empty($result) ? [] : json_decode($result, true);
    }

    /**
     * 监听配置变更回调函数
     * @param  [type] $i    [description]
     * @param  [type] $type [description]
     * @param  String $key  节点路径
     * @return [type]       [description]
     */
    public function watcher($i, $type, $key)
    {
    	//读取最新配置信息并重新设置watcher监听
        $result = $this->pZk->get($key, [$this, 'watcher']);
        //处理配置变更逻辑
        var_dump($result);
    }
}
  1. ConfigFetcher模块

//ConfigFetcher.php
require_once 'ConfigClient.class.php';
$pConfClient = new ConfigClient('127.0.0.1:2181');
$strConfPath = '/serviceA/conf';
$pConfClient->setConfPath($strConfPath);
$result = $pConfClient->getConf();
var_dump(json_encode($result));

while (true) {
    sleep(2);
}
  1. ConfigUpdater模块

//ConfigUpdater.php
require_once 'ConfigClient.class.php';
$pConfClient = new ConfigClient('127.0.0.1:2181');
$strConfPath = '/serviceA/conf';
$pConfClient->setConfPath($strConfPath);

//配置数据
$arrConf = [
    'date' => date('Y-m-d'),
    'time' => time()
];
$result = $pConfClient->setConf($arrConf);
if ($result === false) {
    exit("配置设置失败\n");
}
var_dump(json_encode($arrConf));
exit("配置设置成功\n");

配置测试

  1. 到项目所在目录;
  2. 启动各个服务对应的ConfigFetcher服务,执行php ConfigFetcher.php
  3. 用户更新配置,执行php ConfigUpdater.php
  4. 实际测试效果如下图示
    基于PHP和ZooKeeper的简单配置管理实现_第2张图片
    —————END—————

你可能感兴趣的:(Zookeeper,分布式)