轻量级高性能PHP框架ycroute(高级):集成分布式配置中心QConf

目录:

  • QConf介绍
  • QConf优点
  • QConf架构
  • zookeeper 安装
  • QConf安装部署
  • 使用QConf
  • QConf管理界面安装
  • PHP SDK 扩展
  • 分集群配置 - 不同环境,不同配置
  • 与YCRoute框架集成 - db/redis配置化
  • 灰度发布

QConf介绍:

    QConf 是奇虎360开源的一款分布式配置中心。是一款非常成熟的系统组件,运行3年多,当前超过2万台机器的部署,日处理请求过千亿,并且仍有大量的新业务蜂拥接入,我在360工作的时候,经常会与它打交道。

为什么要用到他呢?

因为它做到了代码和配置的完全分离,避免开发人员被配置文件绑架,也解耦了开发和运维工程师的相互依赖。

尤其是当业务分布较广,配置分布较广的时候,就会很容易地出现一些问题,比如做了负载均衡,需要调整一下应用配置。刚好改漏了一台机,就偶尔出现一些问题,排查起来也是很吃力的。

github:  https://github.com/Qihoo360/QConf

QConf优点

  • 一处修改,所有机器实时同步更新,通过zookeeper 的推送,而不是轮训查询服务器的配置变化,没有无效请求。

  • 相同代码,不同环境,配置不同,在业务运行时,我们开发通常会遇到Test、Beta、Online环境,即使是线上环境也可能需要有多个不同集群,针对这种情况,qconf 保证用户的代码是完全一样,但是不同环境,获取的配置值不同。

  • 高效读取配置,客户端读取配置直接从共享内存获取,性能高。

  • 安装部署方便,使用简单

  • 服务器宕机、网络中断、集群迁移等异常情况,QConf都能保证数据的正确,对用户透明

  • 支持c/c++、php、go、java、shell、luajit、node.js、perl、python 等语言

QConf架构

QConf 由3部分组成,zookeeper 服务、agent、各种语言SDK。

 zookeeper

     zookeeper 服务器用来存储所有的配置信息。它以节点树的形式来组织所有数据,类似于文件系统的目录结构,一个节点有名称和值两个属性,节点下又可以建立若干个子节点,如/a、/b/c、/d/e/f等都是合法的节点名。我们使用节点名代表配置项的名称,如username、timeout等,使用节点值代表配置项的值,如jack、5等。另外它以至少3台服务器组成集群,以提供高可用,它的数据是强一致性。

agent

    agent相当于 ZooKeeper 客户端,与zookeeper 保持长链接,获取、维护zookeeper里的配置信息,并将配置写入本地共享内存,在每台需要用到 qconf 的机器上都需要安装。

   为防止在网络中断的同时机器重启(此时共享内存内容为空,也无法通过网络去zookeeper上取值;同时会打印相关错误日志信息),agent会定期把共享内存里的所有内容持久化到磁盘上的一个dump文件里,保证在上述情况下可以取到上次备份的配置信息。

SDK


     SDK封装了操作共享内存的逻辑,为用户提供读取配置值的接口。

     QConf现在提供多种语言的SDK,包括C/C++、Java、PHP、Python、Lua、Go 等等。

zookeeper 安装

因为QConf 依赖zookeeper,所以我们首先来安装zookeeper

网上找个 zookeeper 安装教程,一大堆。

创建配置节点

[root@gzapi: ~]# zkCli.sh
[zk: localhost:2181(CONNECTED) 0] create /demo demo
[zk: localhost:2181(CONNECTED) 1] create /demo/confs confs
[zk: localhost:2181(CONNECTED) 2] create /demo/confs/conf1 test11111111
[zk: localhost:2181(CONNECTED) 3] create /demo/confs/conf2 test22222222
[zk: localhost:2181(CONNECTED) 4] create /demo/confs/conf3 test33333333

QConf安装部署

安装QConf 有如下两种方式可以安装QConf,可以根据自己的情况来决定:

1. 使用源码安装

git clone https://github.com/Qihoo360/QConf.git
cd QConf 
mkdir build && cd build 
cmake ..
make
make install

默认安装路径为 /usr/local/qconf,通过  cmake .. -DCMAKE_INSTALL_PREFIX=/opt/qconf   可以指定安装路径。

如果安装过程中遇到的 missing aclocal-1.14 的问题参考: https://github.com/Qihoo360/QConf/wiki/FAQ

2.使用rpm 包安装

1) 在 https://github.com/Qihoo360/QConf/releases 根据不同系统下载rpm包

2) rpm -ivh QConf-1.2.1-1.el6.x86_64.rpm

默认安装在 /usr/local/qconf 目录下。

使用QConf

qconf agent 配置

[root@gzapi: ~]# cd /usr/local/qconf/conf
[root@gzapi: /usr/local/qconf/conf]# ls
agent.conf  idc.conf  localidc

如上进入 qconf配置文件:

agent.conf  -  是agent的一些基础设置。

localidc  -  可以认为是存储本机所在集群的名称。

[root@gzapi: /opt/qconf/conf]# cat localidc 
test

idc.conf  - 可以认为是用于配置本机需要访问的QConf所在的集群,如下,该机器可以访问 localidc=test 和 localidc=online 的两个集群, agent 会通过配置的 ip:host 去与相应集群的zookeeper沟通。

############################################################################
#                             QCONF config                                 #
############################################################################
# all the zookeeper host configuration.
#[zookeeper]
zookeeper.test=192.168.20.10:2181,192.168.20.11:2181,192.168.20.12:2181
zookeeper.online=10.10.20.10:2181,10.10.20.11:2181,10.10.20.12:2181

启动 qconf agent

cd /usr/local/qconf
cd bin && sh agent-cmd.sh start
export PATH=$PATH:/usr/local/qconf/bin

shell命令获取配置值

[root@gzapi: /opt/qconf/bin]# qconf get_conf /demo/confs/conf1
test11111111
[root@gzapi: /opt/qconf/bin]# qconf get_batch_keys /demo/confs
conf1
conf2
conf3

QConf管理界面安装

为了完成对zk节点的crud操作,考虑到zookeeper的命令行操作不很友好,为了方面快速使用体验QConf功能,QConf提供了管理端界面来方便操作,QConf 只需要安装在一台机器上即可。

安装

界面本身使用c++编写,同样采用cmake的构建方式。(CMake 版本 2.6及以上)

https://github.com/Qihoo360/QConf/tree/master/manager

进入 manager 目录,通过下面命令安装:

cd QConf/manager
mkdir build && cd build
cmake ..
make
make install

默认的安装目录为 /usr/local/qconf/manage,使用 cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local/qconf_manager 指定安装路径。

使用

进入安装目录,启动web server,默认端口为 8080, 可以通过listening_port 设定

./web_server -listening_port 8080

配置文件中配置zookeeper集群地址,配置文件位置:www/conf/idc.conf

############################################################################
#                             QCONF config                                 #
############################################################################
# all the zookeeper host configuration.
#[zookeeper]
zookeeper.test=192.168.20.10:2181,192.168.20.11:2181,192.168.20.12:2181
zookeeper.online=10.10.20.10:2181,10.10.20.11:2181,10.10.20.12:2181

通过浏览器访问 [SERVER_IP]:8080/qconf_manage.cgi 可以看到如下管理界面:

在上图,我们看到了配置的节点,以及在 www/conf/idc.conf 配置的集群idc列表。

  • QConf Node Infomation 中可以对Zookeeper 上的节点进行添删改查操作,Path输入要操作的节点;Idc选择机房,机房信息对应于www/conf/idc.conf配置文件中的key值;Value显示"Check"后的当前值,并可以修改为新值,并在"Add Or Modify"后生效;“Delete”用来删除节点,前提是没有子节点存在
  • Children Nodes 显示当前节点的所有子节点信息,点击“View”查看详情
  • Parent Node 显示父节点,点击“View”查看详情

PHP SDK 扩展

安装

如下命令编译安装 php 扩展,支持 php 7,其中 --with-libqconf-dir 和 LDFLAGS 指向的是qconf安装目录下的头文件和静态库。

cd QConf/driver/php
/path/to/phpize     #path to is your PHP install dir
./configure --with-php-config=/path/to/php-config --with-libqconf-dir=/usr/local/qconf/include --enable-static LDFLAGS=/usr/local/qconf/lib/libqconf.a
make
make install

API 函数

getConf

getConf(key, idc, get_flag)

Description

获取配置值,最常用

Parameters

key - 配置的key,也就是 zookeeper 的节点路径

idc - 可选,默认是 localidc 文件里指定的本机所在集群,否则到 /usr/local/qconf/conf/idc.conf下配置的idc去取值

get_flag - 可选,set get_标志为0时,如果配置尚未在共享内存中,qconf将等待直到超时,key不存在或第一次获取key时会发生。如果为1,qconf立即返回空,默认get_标志为0

Return Value

成功返回配置值,失败返回NULL

Example

$value = Qconf::getConf("/demo/confs/conf1");

getBatchKeys

getBatchKeys(key, idc, get_flag);

Description

获取所有字节点的 key

Parameters

与 getConf 相同

Return Value

成功返回子节点所有 key 的数组,失败返回NULL

Example

$children_keys = Qconf::getBatchKeys("/demo/confs");

getBatchConf

getBatchConf(key, idc, get_flag);

Description

获取所有字节点的 key 和 value

Parameters

与 getConf 相同

Return Value

成功返回子节点所有 key/value 的数组,失败返回NULL

Example

$children_conf = Qconf::getBatchConf("/demo/confs");

getAllHost

getAllHost(key, idc, get_flag);

Description

获取指定key下的所有可用服务

Parameters

与 getConf 相同

Return Value

成功返回所有host的数组,失败返回NULL

Example

$hosts = Qconf::getAllHost("demo/hosts");

getHost

getHost(key, idc, get_flag);

Description

获取指定key下的一个可用的服务

Parameters

与 getConf 相同

Return Value

成功返回可用的host,失败返回NULL

Example

$host = Qconf::getHost("demo/hosts");

分集群配置 - 不同环境,不同配置

在业务运行时,有可能遇到 测试环境,开发环境,线上环境等等,即使是线上环境也可能需要有多个不同集群,针对这种情况,qconf 保证用户的代码是完全一样,需要做的是,

1)针对不同的环境搭建各自的集群环境,然后在 idc.conf 配置文件中添加相应的服务器信息, 如下 idc.conf:

#                             QCONF config                                 #
############################################################################
# all the zookeeper host configuration.
#[zookeeper]
zookeeper.test=127.0.0.1:2181,192.168.20.10:2181,192.168.20.11:2181
zookeeper.online=10.10.20.10:2181,10.10.20.11:2181,10.10.20.12:2181

2)再将每个环境下的localidc指定为对应的集群名称,如测试环境修改为test,线上环境修改为online。

3)在管理平台的配置文件 /usr/local/qconf/manage/demo/www/conf/idc.conf 把两个集群的也配置上。

#                             QCONF config                                 #
############################################################################
# all the zookeeper host configuration.
#[zookeeper]
zookeeper.test=127.0.0.1:2181,192.168.20.10:2181,192.168.20.11:2181
zookeeper.online=10.10.20.10:2181,10.10.20.11:2181,10.10.20.12:2181

4)然后在管理后台,将online环境idc集群的节点 /demo/confs/conf1 值修改如下:

5) 在两个环境验证:

//test.php
$value = Qconf::getConf("/demo/confs/conf1");
var_dump($value);

从上图我们可以看到,相同的代码,两个环境获取的配置值是不同的,原理就是 agent 根据配置 /usr/local/qconf/conf/localidc 配置的本机所在idc集群,然后到 /usr/local/qconf/conf/idc.conf 中相应idc集群下获取qconf配置。

6)获取其他idc集群配置

当然,我们在Test环境也是可以获取 Online 环境配置的,通过指定idc 如下:

$value = Qconf::getConf("/demo/confs/conf1", "online");
var_dump($value);

从上面可以看到测试环境下的节点取值为 online11111111, 该配置能够成功获取的前提是,本地 /usr/local/qconf/conf/idc.conf 文件中配置了 online idc集群的信息:  zookeeper.online=10.10.20.10:2181,10.10.20.11:2181,10.10.20.12:2181

与YCRoute框架集成 - db/redis配置化

文件读取配置方式

YCRoute 是我写的一个MVC 框架。

https://blog.csdn.net/caohao0591/article/details/87072298

database、redis 在框架中都有各自的代理层, 分别从 framework/application/config/  目录下 database.php 和 redis.php 读取配置。

//database.php
$db['default']['host']     = '127.0.0.1';
$db['default']['username'] = 'root';
$db['default']['password'] = 'test123123';
$db['default']['dbname']   = 'userinfo';
$db['default']['pconnect'] = FALSE;
$db['default']['db_debug'] = TRUE;
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['autoinit'] = FALSE;
$db['default']['port'] = 3306;
//redis.php
$redis_conf['userinfo']['host'] = '127.0.0.1';
$redis_conf['userinfo']['port'] = 6379;

qconf读取方式

以上配置模式在单机情况下,是比较好用,但是在集群情况下,并不算灵活,而且文件IO效率低,远不如共享内存的性能高,

如果采用 qconf 配置,在集群模式下,不仅更加灵活,而且还有这非常高的性能,同时,针对测试环境、线上环境等不同环境,一套代码可以设置不同的配置。

在 YCRoute 中只需将framework中的index.php 中 USE_QCONF 置为 true,然后就可以用Loader::config("/config/user/database"); 即可加载QConf 配置的 database 和 redis,

//index.php
...
define("USE_QCONF", true);
...

 

管理平台配置

使用方式

class UserinfoModel extends Core_Model {
    public function __construct() {
        $this->db = Loader::database('/config/user/database');
        $this->util_log = Logger::get_instance('userinfo_log');
    }

    ...

    public function getUserByName($nickname) {
        return $this->db->query("select * from user_info where nickname like '%$nickname%'");
    }
}

原理代码

function &DBLoader($params = '')
{
    if(USE_QCONF) {
        $config_str = Qconf::getConf($params);
        $config = json_decode($config_str, true);
        if(empty($config_str)) {
            show_error('You have specified an invalid database connection group.');
        }
    } else {
        //config/database.php文本获取配置
        ...
        $config = $db[$params];
    }
    
    require_once(BASEPATH.'/ycdb/YCDB_Driver.php');
    $DB = new YCDB_Driver($config);
    
    if ($DB->autoinit == TRUE) {
        $DB->initialize();
    }
	
    return $DB;
}

Redis的QConf配置

同database 的配置

灰度发布

敬请期待。。。

发布了35 篇原创文章 · 获赞 55 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/caohao0591/article/details/87464206
今日推荐