场景描述
服务端监控/configure目录;
客户端对/configure目录读/写数据,创建/删除子节点
服务端:
监控/configure目录,有数据更新时,输出/configure中的数据;子节点创建/删除时,服务程序列出当前的子目录列表。
代码如下:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <zookeeper.h>
#include <zookeeper_log.h>
#define ZK_CFG_ZNODE_PATH "/configure"
int loop_exit = 0;
static void free_String_vector(struct String_vector *v)
{
int i = 0;
if (v->data)
{
for (i = 0; i < v->count; i++)
{
free(v->data[i]);
}
free(v->data);
v->data = 0;
}
return;
}
int zkServer_read(zhandle_t* zh)
{
int res = 0;
char buffer[100] = {0};
int buf_len = 100;
res = zoo_get(zh, ZK_CFG_ZNODE_PATH, 1, buffer, &buf_len, NULL);
if (ZOK != res)
{
printf("[%s %d] Get data from znode failed(%d)!\n", __FUNCTION__, __LINE__, res);
return -1;
}
if (-1 != buf_len)
{
printf("[%s %d] Data: %s\n", __FUNCTION__, __LINE__, buffer);
if (!strncmp(buffer, "close", 6))
{
loop_exit = 1;
}
}
else
{
printf("[%s %d] The buffer is empty!\n");
}
return 0;
}
int zkServer_get_children(zhandle_t* zh)
{
int res = 0;
int i = 0;
struct String_vector str_vector;
str_vector.data = NULL;
str_vector.count = 0;
res = zoo_get_children(zh, ZK_CFG_ZNODE_PATH, 1, &str_vector);
if (ZOK != res)
{
printf("[%s %d] Get children from znode failed(%d)!\n", __FUNCTION__, __LINE__, res);
return res;
}
printf("[%s %d] There are %d children in znode(/configure)!\n", __FUNCTION__, __LINE__, str_vector.count);
if (0 != str_vector.count)
{
printf("[%s %d] Children: \n", __FUNCTION__, __LINE__);
for (i = 0; i < str_vector.count; i++)
{
printf("%s\n", str_vector.data[i]);
}
}
free_String_vector(&str_vector);
return 0;
}
void zkServer_Watcher_fn(zhandle_t *zh, int type, int state, const char *path, void *watcherCtx)
{
printf("[%s %d] Configure Changed!!!\n", __FUNCTION__, __LINE__);
printf("[%s %d] type: %d\n", __FUNCTION__, __LINE__, type);
printf("[%s %d] state: %d\n", __FUNCTION__, __LINE__, state);
printf("[%s %d] path: %s\n", __FUNCTION__, __LINE__, path);
printf("[%s %d] context: %s\n", __FUNCTION__, __LINE__, (char*)watcherCtx);
if (ZOO_CHANGED_EVENT == type)
{
printf("[%s %d] Data changed!!\n", __FUNCTION__, __LINE__);
zkServer_read(zh);
}
else if (ZOO_CHILD_EVENT == type)
{
printf("[%s %d] Children changed!!\n", __FUNCTION__, __LINE__);
zkServer_get_children(zh);
}
else
{
printf("[%s %d] Other event, ignored!!\n", __FUNCTION__, __LINE__);
}
return;
}
int main(int argc, char** argv)
{
int res = 0;
int exists = 0;
const char* host = "10.10.10.1:2181,10.10.10.2:2181,10.10.10.3:2181";
zhandle_t* zh = zookeeper_init(host, zkServer_Watcher_fn, 30000, 0, "zk_server", 0);
if (NULL == zh)
{
printf("[%s %d] Connect zookeeper failed!\n", __FUNCTION__, __LINE__);
return -1;
}
exists = zoo_exists(zh, ZK_CFG_ZNODE_PATH, 0, NULL);
if (ZNONODE == exists)
{
printf("[%s %d] The znode(/configure) does not exist!\n", __FUNCTION__, __LINE__);
res = zoo_create(zh, ZK_CFG_ZNODE_PATH, NULL, 0, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
if (ZOK != res)
{
printf("[%s %d] Create znode failed(%d)!\n", __FUNCTION__, __LINE__, res);
return -1;
}
}
zkServer_read(zh);
zkServer_get_children(zh);
while (!loop_exit)
{
sleep(1);
}
zookeeper_close(zh);
return 0;
}
编译:
gcc -DTHREADED -L/usr/local/lib/ -lzookeeper_mt -o zk_server zk_cfg_server.c
客户端:
客户端负责创建/删除子节点、znode以及更新/获取znode的数据。
代码如下:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <zookeeper.h>
#include <zookeeper_log.h>
#define ZK_CFG_ZNODE_PATH "/configure"
void zkClient_Watcher_fn(zhandle_t *zh, int type, int state, const char *path, void *watcherCtx)
{
printf("[%s %d] Configure Changed!!!\n", __FUNCTION__, __LINE__);
printf("[%s %d] type: %d\n", __FUNCTION__, __LINE__, type);
printf("[%s %d] state: %d\n", __FUNCTION__, __LINE__, state);
printf("[%s %d] path: %s\n", __FUNCTION__, __LINE__, path);
printf("[%s %d] context: %s\n", __FUNCTION__, __LINE__, (char*)watcherCtx);
return;
}
void zkClient_CreateChild(zhandle_t *zh, char* name)
{
int res = 0;
char childPath[100] = {0};
snprintf(childPath, 100, "%s/%s", ZK_CFG_ZNODE_PATH, name);
printf("\nCreate child: %s\n", childPath);
res = zoo_create(zh, childPath, "child", 5, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
if (ZOK != res)
{
printf("[%s %d] Create znode(%s) failed(%d)!\n", __FUNCTION__, __LINE__, childPath, res);
}
return;
}
void zkClient_DeleteZnode(zhandle_t *zh, char *path)
{
int res = 0;
struct Stat znode_stat;
memset(&znode_stat, 0, sizeof(struct Stat));
res = zoo_exists(zh, path, 0, &znode_stat);
if (ZOK != res)
{
printf("[%s %d] The znode(%s) does not exist!\n", __FUNCTION__, __LINE__, path);
return;
}
res = zoo_delete(zh, path, znode_stat.version);
if (0 != res)
{
printf("[%s %d] Delete znode(%s) failed!\n", __FUNCTION__, __LINE__, path);
}
return;
}
void zkClient_Write(zhandle_t *zh, char* data)
{
int res = 0;
int exists = 0;
struct Stat znode_stat;
printf("\nWrite data: %s\n", data);
memset(&znode_stat, 0, sizeof(struct Stat));
exists = zoo_exists(zh, ZK_CFG_ZNODE_PATH, 0, &znode_stat);
if (ZNONODE == exists)
{
printf("[%s %d] The znode(/configure) does not exist!\n", __FUNCTION__, __LINE__);
return;
}
res = zoo_set(zh, ZK_CFG_ZNODE_PATH, data, strlen(data), znode_stat.version);
if (ZOK != res)
{
printf("[%s %d] Write %s to znode failed(%d)!\n", __FUNCTION__, __LINE__, data, res);
}
return;
}
void zkClient_Read(zhandle_t *zh)
{
int res = 0;
char buffer[100] = {0};
int buf_len = 100;
res = zoo_get(zh, ZK_CFG_ZNODE_PATH, 1, buffer, &buf_len, NULL);
if (ZOK != res)
{
printf("[%s %d] Read data failed(%d)!\n", __FUNCTION__, __LINE__, res);
return;
}
if (-1 != buf_len)
{
printf("[%s %d] Data: %s\n", __FUNCTION__, __LINE__, buffer);
}
return;
}
int main(int argc, char** argv)
{
int selection = 0;
const char* host = "10.10.10.1:2181,10.10.10.2:2181,10.10.10.3:2181";
int loop = 1;
zhandle_t* zh = zookeeper_init(host, zkClient_Watcher_fn, 30000, 0, "zk_client", 0);
if (NULL == zh)
{
printf("zk_client: Connect zookeeper failed!\n");
return -1;
}
do
{
printf("1: Set znode data\n");
printf("2: Get znode data\n");
printf("3: Create child\n");
printf("4: Delete child\n");
printf("5: Delete parent\n");
printf("Select: ");
scanf("%d", &selection);
switch (selection)
{
case 1:
{
zkClient_Write(zh, "Configure Command!");
break;
}
case 2:
{
zkClient_Read(zh);
break;
}
case 3:
{
zkClient_CreateChild(zh, "mysql");
break;
}
case 4:
{
zkClient_DeleteZnode(zh, "/configure/mysql");
break;
}
case 5:
{
zkClient_DeleteZnode(zh, ZK_CFG_ZNODE_PATH);
break;
}
default:
{
loop = 0;
break;
}
}
} while (loop);
zookeeper_close(zh);
return 0;
}
编译:
gcc -DTHREADED -L/usr/local/lib/ -lzookeeper_mt -o zk_client zk_cfg_client.c