Golang使用QConf教程
QConf 是一个分布式配置管理工具。 用来替代传统的配置文件,使得配置信息和程序代码分离,同时配置变化能够实时同步到客户端,而且保证用户高效读取配置,这使的工程师从琐碎的配置修改、代码提交、配置上线流程中解放出来,极大地简化了配置管理工作。
关于QConf的详细介绍可以看这里github.com/Qihoo360/QConf。
特点
- 一处修改,所有机器实时同步更新
- 高效读取配置
- 安装部署方便,使用简单
- 服务器宕机、网络中断、集群迁移等异常情况对用户透明
- 支持c/c++、shell、php、python、lua、java、go、node 等语言
架构
所有客户端通过libqconf,与本机的qconf-agent通过共享内存或消息队列通信。
编译goqconf的时候要使用
#cgo LDFLAGS: -lqconf -lm
如果找不到libqconf,通过查看qconf_agent来看qconf-agent所安装的目录
$ ps aux | grep qconf
root 1098 0.1 1.6 600300 131280 ? Sl Sep25 5:39 /usr/local/qconf/bin/qconf_agent
比如我的qconf-agent安装目录在:/usr/local/qconf/下,则在cgo后加条件-L/usr/local/qconf/lib
这样可以编译成功,但是在运行时还可能报错,找不到libqconf.so文件,这时需要在/usr/lib或/usr/lib64下创建libqconf的软连接:
$ sudo ln -s /usr/local/qconf/lib/libqconf.so /usr/lib64/libqconf.so
$ ll /usr/lib64/libqconf.so
lrwxrwxrwx 1 root root 32 Sep 27 13:17 /usr/lib64/libqconf.so -> /usr/local/qconf/lib/libqconf.so
附上golibqconf.go的代码:
package go_qconf
/*
#cgo LDFLAGS: -lqconf -lm
#include <stdlib.h>
#include <stdio.h>
struct string_vector
{
int count; // the number of services
char **data; // the array of services
};
typedef struct string_vector string_vector_t;
typedef struct qconf_node
{
char *key;
char *value;
} qconf_node;
typedef struct qconf_batch_nodes
{
int count;
qconf_node *nodes;
} qconf_batch_nodes;
int qconf_init();
int qconf_destroy();
int init_string_vector(string_vector_t *nodes);
int destroy_string_vector(string_vector_t *nodes);
int init_qconf_batch_nodes(qconf_batch_nodes *bnodes);
int destroy_qconf_batch_nodes(qconf_batch_nodes *bnodes);
int qconf_get_conf(const char *path, char *buf, int buf_len, const char *idc);
int qconf_get_allhost(const char *path, string_vector_t *nodes, const char *idc);
int qconf_get_host(const char *path, char *buf, int buf_len, const char *idc);
int qconf_get_batch_conf(const char *path, qconf_batch_nodes *bnodes, const char *idc);
int qconf_get_batch_keys(const char *path, string_vector_t *nodes, const char *idc);
*/
import "C"
import (
"fmt"
"reflect"
"unsafe"
)
type Errno int
func (e Errno) Error() string {
s := errText[e]
if s == "" {
return fmt.Sprintf("unknown errno %d", int(e))
}
return s
}