1. 程式人生 > >Zookeeper應用示例(2)——叢集管理

Zookeeper應用示例(2)——叢集管理

場景描述:

啟動一個服務監控/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;
    }