设为首页 收藏本站
查看: 761|回复: 0

[经验分享] Zookeeper场景实践:(5)分布式通知/协调

[复制链接]
累计签到:2 天
连续签到:1 天
发表于 2015-11-22 05:58:14 | 显示全部楼层 |阅读模式

1.基本介绍



通知/协调机制通常有两种方式。


  • 系统调度模式:操作人员发送通知实际是通过控制台改变某个节点的状态,然后Zookeeper将这些变化发送给注册了这个节点的Watcher的所有客户端。
  • 工作汇报模式:这个情况是每个工作进程都在某个目录下创建一个临时节点,并携带工作的进度数据。这样汇总的进程可以监控目录子节点的变化获得工作进度的实时的全局情况。


总的来说,利用Zookeeper的watcher注册和异步通知功能,通知的发送者创建一个节点,并将通知的数据写入的该节点;通知的接受者则对该节点注册watch,当节点变化时,就算作通知的到来。


场景实践



通过上面的说明,其实实现还是非常容易的。看下关键的几个地方:


  • g_monitor_child:变量等于0标识只监控节点,等于1标识监控所有子节点。
  • show_notify(zh,g_path);:打印接受到的通知
  • show_list(zh,g_path);:打印所有子节点的进度


再来看监控函数:

void zktest_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx)  
{  
//监控节点数据变化
if(type == ZOO_CHANGED_EVENT &&
state == ZOO_CONNECTED_STATE &&
g_monitor_child == 0){
show_notify(zh,g_path);
//监控子节点个数变化
}else if(type == ZOO_CHILD_EVENT &&
state == ZOO_CONNECTED_STATE &&
g_monitor_child == 1){
show_list(zh,g_path);
//监控子节点数据变化
}else if(type == ZOO_CHANGED_EVENT &&
state == ZOO_CONNECTED_STATE &&
g_monitor_child == 1){
show_list(zh,g_path);
}
}





下面是完整的代码:

#include<stdio.h>  
#include<string.h>  
#include<unistd.h>
#include&quot;zookeeper.h&quot;  
#include&quot;zookeeper_log.h&quot;  
char g_host[512]= &quot;172.17.0.36:2181&quot;;  
char g_path[512]= &quot;/Notify&quot;;
int g_monitor_child = 0;
//watch function when child list changed
void zktest_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx);
void show_notify(zhandle_t *zkhandle,const char *path);
//show all process ip:pid
void show_list(zhandle_t *zkhandle,const char *path);
void print_usage();
void get_option(int argc,const char* argv[]);
/**********unitl*********************/  
void print_usage()
{
printf(&quot;Usage : [notify] [-h] [-c] [-p path][-s ip:port] \n&quot;);
printf(&quot;        -h Show help\n&quot;);
printf(&quot;        -p path\n&quot;);
printf(&quot;        -c monitor the child nodes\n&quot;);
printf(&quot;        -s zookeeper server ip:port\n&quot;);
printf(&quot;For example:\n&quot;);
printf(&quot;notify -s172.17.0.36:2181 -p /Notify\n&quot;);
}
void get_option(int argc,const char* argv[])
{
extern char    *optarg;
int            optch;
int            dem = 1;
const char    optstring[] = &quot;hcp:s:&quot;;

while((optch = getopt(argc , (char * const *)argv , optstring)) != -1 )
{
switch( optch )
{
case 'h':
print_usage();
exit(-1);
case '?':
print_usage();
printf(&quot;unknown parameter: %c\n&quot;, optopt);
exit(-1);
case ':':
print_usage();
printf(&quot;need parameter: %c\n&quot;, optopt);
exit(-1);
case 'c':
g_monitor_child = 1;
break;
case 's':
strncpy(g_host,optarg,sizeof(g_host));
break;
case 'p':
strncpy(g_path,optarg,sizeof(g_path));
break;
default:
break;
}
}
}
void zktest_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx)  
{  
/*
printf(&quot;watcher event\n&quot;);  
printf(&quot;type: %d\n&quot;, type);  
printf(&quot;state: %d\n&quot;, state);  
printf(&quot;path: %s\n&quot;, path);  
printf(&quot;watcherCtx: %s\n&quot;, (char *)watcherCtx);  
*/
if(type == ZOO_CHANGED_EVENT &&
state == ZOO_CONNECTED_STATE &&
g_monitor_child == 0){
show_notify(zh,g_path);
}else if(type == ZOO_CHILD_EVENT &&
state == ZOO_CONNECTED_STATE &&
g_monitor_child == 1){
show_list(zh,g_path);
}else if(type == ZOO_CHANGED_EVENT &&
state == ZOO_CONNECTED_STATE &&
g_monitor_child == 1){
show_list(zh,g_path);
}
}
void show_notify(zhandle_t *zkhandle,const char *path)
{
char notify_buffer[1024]={0};
int  notify_len = sizeof(notify_buffer);
int ret = zoo_get(zkhandle,g_path,1,notify_buffer,&#172;ify_len,NULL);
if(ret != ZOK){
fprintf(stderr,&quot;failed to get the data of path %s!\n&quot;,g_path);
}else{
printf(&quot;Notice:%s\n&quot;,notify_buffer);
}
}
void show_list(zhandle_t *zkhandle,const char *path)
{
struct String_vector children;
int i = 0;
int ret = zoo_get_children(zkhandle,path,1,&children);
if(ret == ZOK){
char child_path[512] ={0};
char notify_buffer[1024] = {0};
int notify_len = sizeof(notify_buffer);
printf(&quot;--------------\n&quot;);
for(i = 0; i < children.count; ++i){
sprintf(child_path,&quot;%s/%s&quot;,g_path,children.data);
ret = zoo_get(zkhandle,child_path,1,notify_buffer,&#172;ify_len,NULL);
if(ret != ZOK){
fprintf(stderr,&quot;failed to get the data of path %s!\n&quot;,child_path);
}else{
printf(&quot;%s:%s\n&quot;,children.data,notify_buffer);
}
}
}else{
fprintf(stderr,&quot;failed to get the children of path %s!\n&quot;,path);
}
for(i = 0; i < children.count; ++i){
free(children.data);
children.data = NULL;
}
}
int main(int argc, const char *argv[])  
{  
int timeout = 30000;  
char path_buffer[512];  
int bufferlen=sizeof(path_buffer);  
zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); //设置日志级别,避免出现一些其他信息  
get_option(argc,argv);
zhandle_t* zkhandle = zookeeper_init(g_host,zktest_watcher_g, timeout, 0, (char *)&quot;Notify Test&quot;, 0);  
if (zkhandle ==NULL)  
{  
fprintf(stderr, &quot;Error when connecting to zookeeper servers...\n&quot;);  
exit(EXIT_FAILURE);  
}  
int ret = zoo_exists(zkhandle,g_path,0,NULL);
if(ret != ZOK){
ret = zoo_create(zkhandle,g_path,&quot;1.0&quot;,strlen(&quot;1.0&quot;),  
&ZOO_OPEN_ACL_UNSAFE,0,  
path_buffer,bufferlen);  
if(ret != ZOK){
fprintf(stderr,&quot;failed to create the path %s!\n&quot;,g_path);
}else{
printf(&quot;create path %s successfully!\n&quot;,g_path);
}
}
if(ret == ZOK && g_monitor_child == 0){
show_notify(zkhandle,g_path);
}else if(ret == ZOK && g_monitor_child == 1){
show_list(zkhandle,g_path);
}
getchar();
zookeeper_close(zkhandle);
return 0;
}





程序由3个参数选项


  • -s:指定Zookeeper的服务器的ip:port
  • -p:指定要监控的路径,默认为/Notify
  • -c:使用此项表示监控子节点列表



notify -s172.17.0.36:2181 -p /Notify

当你在客户端修改数据的时候,程序就能收到对应的通知了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-141948-1-1.html 上篇帖子: Ubuntu下ZooKeeper安装过程 下篇帖子: Zookeeper笔记(安装)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表