Zookeeper C API應用示例(1)——配置管理(同步API)
阿新 • • 發佈:2018-11-17
場景描述
服務端監控/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