Zookeeper應用示例(2)——叢集管理
阿新 • • 發佈:2018-11-17
場景描述:
啟動一個服務監控/cluster目錄,啟動3個客戶端(執行在3個虛機上),分別在/cluster目錄上建立三個臨時目錄,然後分別休眠5分鐘。
目的:
為了驗證在客戶端正常結束(呼叫zookeeper_close)、CTRL+C異常結束以及虛機Reboot之後,監控服務多長時間可以檢測到客戶端離線。
結論:
1)若客戶端正常結束,服務端立即就能感知到客戶端離線;
2)若CTRL+C提前終止客戶端程式,則服務端延遲30s後感知到客戶端離線;
3)若重啟虛機,則服務端延遲30s後感知到客戶端離線;
服務端程式碼:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <zookeeper.h> #include <zookeeper_log.h> #define ZK_CFG_ZNODE_PATH "/cluster" 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(/cluster)!\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 = "xxx.xxx.xxx.xxx:2181,xxx.xxx.xxx.xxx:2181,xxx.xxx.xxx.xxx: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(/cluster) 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; }
客戶端程式碼:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <zookeeper.h> #include <zookeeper_log.h> #define ZK_CLUSTER_PATH "/cluster" void zkCluster_Watch_fn(zhandle_t *zh, int type, int state, const char *path, void *watchCtx) { printf("[%s %d] Something happened!\n", __FUNCTION__, __LINE__); printf("type: %d\n", type); printf("state: %d\n", state); printf("path: %s\n", path); printf("context: %s\n", watchCtx); return; } int main(int argc, char** argv) { int res = 0; const char* host = "xxx.xxx.xxx.xxx:2181,xxx.xxx.xxx.xxx:2181,xxx.xxx.xxx.xxx:2181"; char* child_path = "/cluster/10.43.17.38"; zhandle_t *zh = zookeeper_init(host, zkCluster_Watch_fn, 30000, 0, "zkClusterClient", 0); if (NULL == zh) { printf("Connect zookeeper failed!\n"); return -1; } res = zoo_exists(zh, ZK_CLUSTER_PATH, 0, NULL); if (ZNONODE == res) { printf("[%s %d] The znode(/cluster) does not exist!\n", __FUNCTION__, __LINE__); res = zoo_create(zh, ZK_CLUSTER_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; } } /* Create temporary directory */ res = zoo_create(zh, child_path, NULL, 0, &ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL, NULL, 0); if (ZOK != res) { printf("[%s %d] Create child(%s) failed(%d)!\n", __FUNCTION__, __LINE__, res); return -1; } sleep(300); zookeeper_close(zh); return 0; }