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;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值