├── ClusterMonitor ├── Makefile └── monitor.c ├── Config ├── Makefile ├── inifile.cpp ├── inifile.h ├── stringutil.cpp ├── stringutil.h ├── test.cpp └── test.ini ├── Lock ├── Makefile └── lock.c ├── NameService ├── Makefile └── nameservice.c ├── Notify ├── Makefile └── notify.c ├── Queue ├── Makefile └── queue.c ├── README.md └── mymetaq ├── Makefile ├── consumer.c └── producer.c /ClusterMonitor/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | HOME=/home/chenxueyou 3 | CFLAGS=-g 4 | ZOOKEEPER_INC=-I${HOME}/zookeeper/include/zookeeper 5 | ZOOKEEPER_LIB= -L${HOME}/zookeeper/lib -lzookeeper_mt 6 | 7 | APP=monitor 8 | all: 9 | ${CC} monitor.c -DTHREAD ${CFLAGS} ${ZOOKEEPER_INC} ${ZOOKEEPER_LIB} -o ${APP} 10 | clean: 11 | rm -f ${APP} 12 | -------------------------------------------------------------------------------- /ClusterMonitor/monitor.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include"zookeeper.h" 8 | #include"zookeeper_log.h" 9 | 10 | enum WORK_MODE{MODE_MONITOR,MODE_WORKER} g_mode; 11 | char g_host[512]= "172.17.0.36:2181"; 12 | 13 | //watch function when child list changed 14 | void zktest_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx); 15 | //show all process ip:pid 16 | void show_list(zhandle_t *zkhandle,const char *path); 17 | //if success,the g_mode will become MODE_MONITOR 18 | void choose_mater(zhandle_t *zkhandle,const char *path); 19 | //get localhost ip:pid 20 | void getlocalhost(char *ip_pid,int len); 21 | 22 | void print_usage(); 23 | void get_option(int argc,const char* argv[]); 24 | 25 | /**********unitl*********************/ 26 | void print_usage() 27 | { 28 | printf("Usage : [monitor] [-h] [-m] [-s ip:port] \n"); 29 | printf(" -h Show help\n"); 30 | printf(" -m set monitor mode\n"); 31 | printf(" -s server ip:port\n"); 32 | printf("For example:\n"); 33 | printf("monitor -m -s172.17.0.36:2181 \n"); 34 | } 35 | 36 | void get_option(int argc,const char* argv[]) 37 | { 38 | extern char *optarg; 39 | int optch; 40 | int dem = 1; 41 | const char optstring[] = "hms:"; 42 | 43 | //default 44 | g_mode = MODE_WORKER; 45 | 46 | while((optch = getopt(argc , (char * const *)argv , optstring)) != -1 ) 47 | { 48 | switch( optch ) 49 | { 50 | case 'h': 51 | print_usage(); 52 | exit(-1); 53 | case '?': 54 | print_usage(); 55 | printf("unknown parameter: %c\n", optopt); 56 | exit(-1); 57 | case ':': 58 | print_usage(); 59 | printf("need parameter: %c\n", optopt); 60 | exit(-1); 61 | case 'm': 62 | g_mode = MODE_MONITOR; 63 | break; 64 | case 's': 65 | strncpy(g_host,optarg,sizeof(g_host)); 66 | break; 67 | default: 68 | break; 69 | } 70 | } 71 | } 72 | void zktest_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx) 73 | { 74 | /* 75 | printf("watcher event\n"); 76 | printf("type: %d\n", type); 77 | printf("state: %d\n", state); 78 | printf("path: %s\n", path); 79 | printf("watcherCtx: %s\n", (char *)watcherCtx); 80 | */ 81 | 82 | if(type == ZOO_CHILD_EVENT && 83 | state == ZOO_CONNECTED_STATE ){ 84 | 85 | choose_mater(zh,path); 86 | if(g_mode == MODE_MONITOR){ 87 | show_list(zh,path); 88 | } 89 | } 90 | } 91 | void getlocalhost(char *ip_pid,int len) 92 | { 93 | char hostname[64] = {0}; 94 | struct hostent *hent ; 95 | 96 | gethostname(hostname,sizeof(hostname)); 97 | hent = gethostbyname(hostname); 98 | 99 | char * localhost = inet_ntoa(*((struct in_addr*)(hent->h_addr_list[0]))); 100 | 101 | snprintf(ip_pid,len,"%s:%lld",localhost,getpid()); 102 | } 103 | 104 | void choose_mater(zhandle_t *zkhandle,const char *path) 105 | { 106 | struct String_vector procs; 107 | int i = 0; 108 | int ret = zoo_get_children(zkhandle,path,1,&procs); 109 | 110 | if(ret != ZOK || procs.count == 0){ 111 | fprintf(stderr,"failed to get the children of path %s!\n",path); 112 | }else{ 113 | char master_path[512] ={0}; 114 | char ip_pid[64] = {0}; 115 | int ip_pid_len = sizeof(ip_pid); 116 | 117 | char master[512]={0}; 118 | char localhost[512]={0}; 119 | 120 | getlocalhost(localhost,sizeof(localhost)); 121 | 122 | strcpy(master,procs.data[0]); 123 | for(i = 1; i < procs.count; ++i){ 124 | if(strcmp(master,procs.data[i])>0){ 125 | strcpy(master,procs.data[i]); 126 | } 127 | } 128 | 129 | sprintf(master_path,"%s/%s",path,master); 130 | 131 | ret = zoo_get(zkhandle,master_path,0,ip_pid,&ip_pid_len,NULL); 132 | if(ret != ZOK){ 133 | fprintf(stderr,"failed to get the data of path %s!\n",master_path); 134 | }else if(strcmp(ip_pid,localhost)==0){ 135 | g_mode = MODE_MONITOR; 136 | } 137 | 138 | } 139 | 140 | for(i = 0; i < procs.count; ++i){ 141 | free(procs.data[i]); 142 | procs.data[i] = NULL; 143 | } 144 | 145 | } 146 | void show_list(zhandle_t *zkhandle,const char *path) 147 | { 148 | 149 | struct String_vector procs; 150 | int i = 0; 151 | char localhost[512]={0}; 152 | 153 | getlocalhost(localhost,sizeof(localhost)); 154 | 155 | int ret = zoo_get_children(zkhandle,path,1,&procs); 156 | 157 | if(ret != ZOK){ 158 | fprintf(stderr,"failed to get the children of path %s!\n",path); 159 | }else{ 160 | char child_path[512] ={0}; 161 | char ip_pid[64] = {0}; 162 | int ip_pid_len = sizeof(ip_pid); 163 | printf("--------------\n"); 164 | printf("ip\tpid\n"); 165 | for(i = 0; i < procs.count; ++i){ 166 | sprintf(child_path,"%s/%s",path,procs.data[i]); 167 | //printf("%s\n",child_path); 168 | ret = zoo_get(zkhandle,child_path,0,ip_pid,&ip_pid_len,NULL); 169 | if(ret != ZOK){ 170 | fprintf(stderr,"failed to get the data of path %s!\n",child_path); 171 | }else if(strcmp(ip_pid,localhost)==0){ 172 | printf("%s(Master)\n",ip_pid); 173 | }else{ 174 | printf("%s\n",ip_pid); 175 | } 176 | } 177 | } 178 | 179 | for(i = 0; i < procs.count; ++i){ 180 | free(procs.data[i]); 181 | procs.data[i] = NULL; 182 | } 183 | } 184 | 185 | int main(int argc, const char *argv[]) 186 | { 187 | int timeout = 30000; 188 | char path_buffer[512]; 189 | int bufferlen=sizeof(path_buffer); 190 | 191 | zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); //设置日志级别,避免出现一些其他信息 192 | 193 | get_option(argc,argv); 194 | 195 | zhandle_t* zkhandle = zookeeper_init(g_host,zktest_watcher_g, timeout, 0, (char *)"Monitor Test", 0); 196 | 197 | if (zkhandle ==NULL) 198 | { 199 | fprintf(stderr, "Error when connecting to zookeeper servers...\n"); 200 | exit(EXIT_FAILURE); 201 | } 202 | 203 | char path[512]="/Monitor"; 204 | 205 | int ret = zoo_exists(zkhandle,path,0,NULL); 206 | if(ret != ZOK){ 207 | ret = zoo_create(zkhandle,path,"1.0",strlen("1.0"), 208 | &ZOO_OPEN_ACL_UNSAFE,0, 209 | path_buffer,bufferlen); 210 | if(ret != ZOK){ 211 | fprintf(stderr,"failed to create the path %s!\n",path); 212 | }else{ 213 | printf("create path %s successfully!\n",path); 214 | } 215 | } 216 | 217 | if(ret == ZOK && g_mode == MODE_WORKER){ 218 | 219 | char localhost[512]={0}; 220 | getlocalhost(localhost,sizeof(localhost)); 221 | 222 | char child_path[512]; 223 | sprintf(child_path,"%s/proc-",path); 224 | ret = zoo_create(zkhandle,child_path,localhost,strlen(localhost), 225 | &ZOO_OPEN_ACL_UNSAFE,ZOO_SEQUENCE|ZOO_EPHEMERAL, 226 | path_buffer,bufferlen); 227 | if(ret != ZOK){ 228 | fprintf(stderr,"failed to create the child_path %s,buffer:%s!\n",child_path,path_buffer); 229 | }else{ 230 | printf("create child path %s successfully!\n",path_buffer); 231 | } 232 | choose_mater(zkhandle,path); 233 | 234 | } 235 | 236 | if(g_mode == MODE_MONITOR){ 237 | show_list(zkhandle,path); 238 | } 239 | 240 | getchar(); 241 | 242 | zookeeper_close(zkhandle); 243 | 244 | return 0; 245 | } 246 | -------------------------------------------------------------------------------- /Config/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CC=g++ 3 | 4 | HOME=/home/chenxueyou 5 | ZOOKEEPER_INC=-I${HOME}/zookeeper/include/zookeeper 6 | ZOOKEEPER_LIB= -L${HOME}/zookeeper/lib -lzookeeper_mt 7 | 8 | CPPFLAGS=-Isrc/ -Dprotected=public -Dprivate=public 9 | all: testcase 10 | 11 | testcase: 12 | $(CC) $(CPPFLAGS) ${ZOOKEEPER_INC} -g -c inifile.cpp 13 | $(CC) $(CPPFLAGS) ${ZOOKEEPER_INC} -g -c stringutil.cpp 14 | $(CC) $(CPPFLAGS) ${ZOOKEEPER_INC} -g -c test.cpp 15 | $(CC) ${CPPFLAGS} ${ZOOKEEPER_INC} ${ZOOKEEPER_LIB} -DTHREAD -g -o testcase test.o inifile.o stringutil.o 16 | clean: 17 | rm -f *.o testcase 18 | 19 | -------------------------------------------------------------------------------- /Config/inifile.cpp: -------------------------------------------------------------------------------- 1 | #ifndef _INIFILE_CPP 2 | #define _INIFILE_CPP 3 | 4 | #include "stringutil.h" 5 | #include "inifile.h" 6 | #include 7 | #include 8 | #include"zookeeper.h" 9 | #include"zookeeper_log.h" 10 | 11 | namespace inifile{ 12 | using namespace stringutil; 13 | 14 | int INI_BUF_SIZE=2048; 15 | IniFile::IniFile() 16 | { 17 | flags_.push_back("#"); 18 | flags_.push_back(";"); 19 | } 20 | bool IniFile::parse(const string &content,string &key,string &value,char c/*= '='*/) 21 | { 22 | int i = 0; 23 | int len = content.length(); 24 | 25 | while(i < len && content[i] != c){ 26 | ++i; 27 | } 28 | if(i >= 0 && i < len){ 29 | key = string(content.c_str(),i); 30 | value = string(content.c_str()+i+1,len-i-1); 31 | return true; 32 | } 33 | 34 | return false; 35 | } 36 | 37 | int IniFile::getline(string &str,FILE *fp) 38 | { 39 | int plen = 0; 40 | int buf_size = INI_BUF_SIZE*sizeof(char); 41 | 42 | char *buf =(char *) malloc(buf_size); 43 | char *pbuf = NULL; 44 | char * p = buf; 45 | 46 | if(buf == NULL){ 47 | fprintf(stderr,"no enough memory!exit!\n"); 48 | exit(-1); 49 | } 50 | 51 | memset(buf,0,buf_size); 52 | int total_size = buf_size; 53 | while(fgets(p,buf_size,fp) != NULL){ 54 | plen = strlen(p); 55 | 56 | if( plen > 0 && p[plen-1] != '\n' && !feof(fp)){ 57 | 58 | total_size = strlen(buf)+buf_size; 59 | pbuf = (char *)realloc(buf,total_size); 60 | 61 | if(pbuf == NULL){ 62 | free(buf); 63 | fprintf(stderr,"no enough memory!exit!\n"); 64 | exit(-1); 65 | } 66 | 67 | buf = pbuf; 68 | 69 | p = buf + strlen(buf); 70 | 71 | continue; 72 | }else{ 73 | break; 74 | } 75 | } 76 | 77 | str = buf; 78 | 79 | free(buf); 80 | buf = NULL; 81 | return str.length(); 82 | 83 | } 84 | int IniFile::open(const string &filename) 85 | { 86 | release(); 87 | fname_ = filename; 88 | IniSection *section = NULL; 89 | FILE *fp = fopen(filename.c_str(),"r"); 90 | 91 | if(fp == NULL ){ 92 | return -1; 93 | } 94 | 95 | string line; 96 | string comment; 97 | 98 | //增加默认段 99 | section = new IniSection(); 100 | sections_[""] = section; 101 | 102 | while(getline(line,fp) > 0){ 103 | 104 | trimright(line,'\n'); 105 | trimright(line,'\r'); 106 | trim(line); 107 | 108 | if(line.length() <= 0){ 109 | continue; 110 | } 111 | 112 | if(line[0] == '['){ 113 | section = NULL; 114 | int index = line.find_first_of(']'); 115 | 116 | if(index == -1){ 117 | fclose(fp); 118 | fprintf(stderr,"没有找到匹配的]\n"); 119 | return -1; 120 | } 121 | int len = index-1; 122 | if(len <= 0){ 123 | fprintf(stderr,"段为空\n"); 124 | continue; 125 | } 126 | string s(line,1,len); 127 | 128 | if(getSection(s.c_str()) != NULL){ 129 | fclose(fp); 130 | fprintf(stderr,"此段已存在:%s\n",s.c_str()); 131 | return -1; 132 | } 133 | 134 | section = new IniSection(); 135 | sections_[s] = section; 136 | 137 | section->name = s; 138 | section->comment = comment; 139 | comment = ""; 140 | }else if(isComment(line)){ 141 | if(comment != ""){ 142 | comment += delim + line ; 143 | }else{ 144 | comment = line; 145 | } 146 | }else{ 147 | string key,value; 148 | if(parse(line,key,value)){ 149 | IniItem item; 150 | item.key = key; 151 | item.value = value; 152 | item.comment = comment; 153 | 154 | section->items.push_back(item); 155 | }else{ 156 | fprintf(stderr,"解析参数失败[%s]\n",line.c_str()); 157 | } 158 | comment = ""; 159 | } 160 | 161 | } 162 | 163 | fclose(fp); 164 | 165 | return 0; 166 | } 167 | 168 | 169 | string zkopen(const string &host,const string &filepath,char *fp,int len) 170 | { 171 | int timeout = 30000; 172 | char path_buffer[512]; 173 | int bufferlen=sizeof(path_buffer); 174 | char conf_data[2048]; 175 | int conf_len=sizeof(conf_data); 176 | 177 | zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); //设置日志级别,避免出现一些其他信息 178 | 179 | zhandle_t* zkhandle = zookeeper_init(host.c_str(),NULL, timeout, 0, (char *)"Monitor Test", 0); 180 | 181 | if (zkhandle ==NULL) 182 | { 183 | fprintf(stderr, "Error when connecting to zookeeper servers...\n"); 184 | exit(EXIT_FAILURE); 185 | } 186 | 187 | int ret = zoo_get(zkhandle,filepath.c_str(),0,conf_data,&conf_len,NULL); 188 | if(ret != ZOK){ 189 | fprintf(stderr,"failed to get the data of path %s!\n",filepath.c_str()); 190 | conf_data[0] = 0; 191 | } 192 | 193 | zookeeper_close(zkhandle); 194 | 195 | strncpy(fp,conf_data,len); 196 | return conf_data; 197 | 198 | } 199 | 200 | int getline2(string &str,char * &src) 201 | { 202 | char *p = index(src,'\n'); 203 | 204 | while(p == src && src != NULL){ 205 | src = src+1; 206 | p = index(src,'\n'); 207 | } 208 | if(src == NULL){ 209 | str = ""; 210 | }else if (p == NULL && src != NULL){ 211 | str = src; 212 | src = NULL; 213 | }else{ 214 | str = string(src,p-src); 215 | src = p+1; 216 | } 217 | 218 | return str.length(); 219 | } 220 | 221 | int IniFile::open2(const string &host,const string &filepath) 222 | { 223 | release(); 224 | fname_ = filepath; 225 | IniSection *section = NULL; 226 | char fp[2048]={0}; 227 | 228 | zkopen(host,filepath,fp,sizeof(fp)); 229 | 230 | if(fp[0] == 0){ 231 | return -1; 232 | } 233 | 234 | string line; 235 | string comment; 236 | 237 | //增加默认段 238 | section = new IniSection(); 239 | sections_[""] = section; 240 | 241 | char *p = fp; 242 | while(getline2(line,p) > 0){ 243 | 244 | trimright(line,'\n'); 245 | trimright(line,'\r'); 246 | trim(line); 247 | 248 | if(line.length() <= 0){ 249 | continue; 250 | } 251 | 252 | if(line[0] == '['){ 253 | section = NULL; 254 | int index = line.find_first_of(']'); 255 | 256 | if(index == -1){ 257 | fprintf(stderr,"没有找到匹配的]\n"); 258 | return -1; 259 | } 260 | int len = index-1; 261 | if(len <= 0){ 262 | fprintf(stderr,"段为空\n"); 263 | continue; 264 | } 265 | string s(line,1,len); 266 | 267 | if(getSection(s.c_str()) != NULL){ 268 | fprintf(stderr,"此段已存在:%s\n",s.c_str()); 269 | return -1; 270 | } 271 | 272 | section = new IniSection(); 273 | sections_[s] = section; 274 | 275 | section->name = s; 276 | section->comment = comment; 277 | comment = ""; 278 | }else if(isComment(line)){ 279 | if(comment != ""){ 280 | comment += delim + line ; 281 | }else{ 282 | comment = line; 283 | } 284 | }else{ 285 | string key,value; 286 | if(parse(line,key,value)){ 287 | IniItem item; 288 | item.key = key; 289 | item.value = value; 290 | item.comment = comment; 291 | 292 | section->items.push_back(item); 293 | }else{ 294 | fprintf(stderr,"解析参数失败[%s]\n",line.c_str()); 295 | } 296 | comment = ""; 297 | } 298 | 299 | } 300 | 301 | 302 | return 0; 303 | } 304 | 305 | int IniFile::save() 306 | { 307 | return saveas(fname_); 308 | } 309 | 310 | int IniFile::saveas(const string &filename) 311 | { 312 | string data = ""; 313 | for(iterator sect = sections_.begin(); sect != sections_.end(); ++sect){ 314 | if(sect->second->comment != ""){ 315 | data += sect->second->comment; 316 | data += delim; 317 | } 318 | if(sect->first != ""){ 319 | data += string("[")+sect->first + string("]"); 320 | data += delim; 321 | } 322 | 323 | for(IniSection::iterator item = sect->second->items.begin(); item != sect->second->items.end(); ++item){ 324 | if(item->comment != ""){ 325 | data += item->comment; 326 | data += delim; 327 | } 328 | data += item->key+"="+item->value; 329 | data += delim; 330 | } 331 | } 332 | 333 | FILE *fp = fopen(filename.c_str(),"w"); 334 | 335 | fwrite(data.c_str(),1,data.length(),fp); 336 | 337 | fclose(fp); 338 | 339 | return 0; 340 | } 341 | IniSection *IniFile::getSection(const string §ion /*=""*/) 342 | { 343 | iterator it = sections_.find(section); 344 | if(it != sections_.end()){ 345 | return it->second; 346 | } 347 | 348 | return NULL; 349 | } 350 | 351 | string IniFile::getStringValue(const string §ion,const string &key,int &ret) 352 | { 353 | string value,comment; 354 | 355 | ret = getValue(section,key,value,comment); 356 | 357 | return value; 358 | } 359 | 360 | int IniFile::getIntValue(const string §ion,const string &key,int &ret) 361 | { 362 | string value,comment; 363 | 364 | ret = getValue(section,key,value,comment); 365 | 366 | return atoi(value.c_str()); 367 | } 368 | 369 | double IniFile::getDoubleValue(const string §ion,const string &key,int &ret) 370 | { 371 | string value,comment; 372 | 373 | ret = getValue(section,key,value,comment); 374 | 375 | return atof(value.c_str()); 376 | 377 | } 378 | 379 | int IniFile::getValue(const string §ion,const string &key,string &value) 380 | { 381 | string comment; 382 | return getValue(section,key,value,comment); 383 | } 384 | int IniFile::getValue(const string §ion,const string &key,string &value,string &comment) 385 | { 386 | IniSection * sect = getSection(section); 387 | 388 | if(sect != NULL){ 389 | for(IniSection::iterator it = sect->begin(); it != sect->end(); ++it){ 390 | if(it->key == key){ 391 | value = it->value; 392 | comment = it->comment; 393 | return RET_OK; 394 | } 395 | } 396 | } 397 | 398 | return RET_ERR; 399 | } 400 | int IniFile::getValues(const string §ion,const string &key,vector &values) 401 | { 402 | vector comments; 403 | return getValues(section,key,values,comments); 404 | } 405 | int IniFile::getValues(const string §ion,const string &key, 406 | vector &values,vector &comments) 407 | { 408 | string value,comment; 409 | 410 | values.clear(); 411 | comments.clear(); 412 | 413 | IniSection * sect = getSection(section); 414 | 415 | if(sect != NULL){ 416 | for(IniSection::iterator it = sect->begin(); it != sect->end(); ++it){ 417 | if(it->key == key){ 418 | value = it->value; 419 | comment = it->comment; 420 | 421 | values.push_back(value); 422 | comments.push_back(comment); 423 | } 424 | } 425 | } 426 | 427 | return (values.size() ? RET_OK : RET_ERR); 428 | 429 | } 430 | bool IniFile::hasSection(const string §ion) 431 | { 432 | return (getSection(section) != NULL); 433 | 434 | } 435 | 436 | bool IniFile::hasKey(const string §ion,const string &key) 437 | { 438 | IniSection * sect = getSection(section); 439 | 440 | if(sect != NULL){ 441 | for(IniSection::iterator it = sect->begin(); it != sect->end(); ++it){ 442 | if(it->key == key){ 443 | return true; 444 | } 445 | } 446 | } 447 | 448 | return false; 449 | } 450 | int IniFile::getSectionComment(const string §ion,string & comment) 451 | { 452 | comment = ""; 453 | IniSection * sect = getSection(section); 454 | 455 | if(sect != NULL){ 456 | comment = sect->comment; 457 | return RET_OK; 458 | } 459 | 460 | return RET_ERR; 461 | } 462 | int IniFile::setSectionComment(const string §ion,const string & comment) 463 | { 464 | IniSection * sect = getSection(section); 465 | 466 | if(sect != NULL){ 467 | sect->comment = comment; 468 | return RET_OK; 469 | } 470 | 471 | return RET_ERR; 472 | } 473 | 474 | int IniFile::setValue(const string §ion,const string &key, 475 | const string &value,const string &comment /*=""*/) 476 | { 477 | IniSection * sect = getSection(section); 478 | 479 | string comt = comment; 480 | if (comt != ""){ 481 | comt = flags_[0] +comt; 482 | } 483 | if(sect == NULL){ 484 | sect = new IniSection(); 485 | if(sect == NULL){ 486 | fprintf(stderr,"no enough memory!\n"); 487 | exit(-1); 488 | } 489 | sect->name = section; 490 | sections_[section] = sect; 491 | } 492 | 493 | for(IniSection::iterator it = sect->begin(); it != sect->end(); ++it){ 494 | if(it->key == key){ 495 | it->value = value; 496 | it->comment = comt; 497 | return RET_OK; 498 | } 499 | } 500 | 501 | //not found key 502 | IniItem item; 503 | item.key = key; 504 | item.value = value; 505 | item.comment = comt; 506 | 507 | sect->items.push_back(item); 508 | 509 | return RET_OK; 510 | 511 | } 512 | void IniFile::getCommentFlags(vector &flags) 513 | { 514 | flags = flags_; 515 | } 516 | void IniFile::setCommentFlags(const vector &flags) 517 | { 518 | flags_ = flags; 519 | } 520 | void IniFile::deleteSection(const string §ion) 521 | { 522 | IniSection *sect = getSection(section); 523 | 524 | if(sect != NULL){ 525 | 526 | sections_.erase(section); 527 | delete sect; 528 | } 529 | } 530 | void IniFile::deleteKey(const string §ion,const string &key) 531 | { 532 | IniSection * sect = getSection(section); 533 | 534 | if(sect != NULL){ 535 | for(IniSection::iterator it = sect->begin(); it != sect->end(); ++it){ 536 | if(it->key == key){ 537 | sect->items.erase(it); 538 | break; 539 | } 540 | } 541 | } 542 | 543 | } 544 | 545 | void IniFile::release() 546 | { 547 | fname_ = ""; 548 | 549 | for(iterator i = sections_.begin(); i != sections_.end(); ++i){ 550 | delete i->second; 551 | } 552 | 553 | sections_.clear(); 554 | 555 | } 556 | 557 | bool IniFile::isComment(const string &str) 558 | { 559 | bool ret =false; 560 | for(int i = 0; i < flags_.size(); ++i){ 561 | int k = 0; 562 | if(str.length() < flags_[i].length()){ 563 | continue; 564 | } 565 | for(k = 0;k < flags_[i].length(); ++k){ 566 | if(str[k] != flags_[i][k]){ 567 | break; 568 | } 569 | } 570 | 571 | if(k == flags_[i].length()){ 572 | ret = true; 573 | break; 574 | } 575 | } 576 | 577 | return ret; 578 | } 579 | //for debug 580 | void IniFile::print() 581 | { 582 | printf("filename:[%s]\n",fname_.c_str()); 583 | 584 | printf("flags_:["); 585 | for(int i = 0; i < flags_.size(); ++i){ 586 | printf(" %s ",flags_[i].c_str()); 587 | } 588 | printf("]\n"); 589 | 590 | for(iterator it = sections_.begin(); it != sections_.end(); ++it){ 591 | printf("section:[%s]\n",it->first.c_str()); 592 | printf("comment:[%s]\n",it->second->comment.c_str()); 593 | for(IniSection::iterator i = it->second->items.begin(); i != it->second->items.end(); ++i){ 594 | printf(" comment:%s\n",i->comment.c_str()); 595 | printf(" parm :%s=%s\n",i->key.c_str(),i->value.c_str()); 596 | } 597 | } 598 | } 599 | } 600 | #endif 601 | -------------------------------------------------------------------------------- /Config/inifile.h: -------------------------------------------------------------------------------- 1 | #ifndef _INIFILE_H 2 | #define _INIFILE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | namespace inifile 11 | { 12 | const int RET_OK = 0; 13 | const int RET_ERR = -1; 14 | const string delim = "\n"; 15 | struct IniItem 16 | { 17 | string key; 18 | string value; 19 | string comment; 20 | }; 21 | struct IniSection 22 | { 23 | typedef vector::iterator iterator; 24 | iterator begin() {return items.begin();} 25 | iterator end() {return items.end();} 26 | 27 | string name; 28 | string comment; 29 | vector items; 30 | }; 31 | 32 | class IniFile 33 | { 34 | public: 35 | IniFile(); 36 | ~IniFile(){release();} 37 | 38 | public: 39 | typedef map::iterator iterator; 40 | 41 | iterator begin() {return sections_.begin();} 42 | iterator end() {return sections_.end();} 43 | public: 44 | /* 打开并解析一个名为fname的INI文件 */ 45 | int open(const string &fname); 46 | /* 打开Zookeeper管理的一个路径下数据,host为Zookeeper服务器地址,filepath为数据所在路径 */ 47 | int open2(const string &host,const string &filepath); 48 | /*将内容保存到当前文件*/ 49 | int save(); 50 | /*将内容另存到一个名为fname的文件*/ 51 | int saveas(const string &fname); 52 | 53 | /*获取section段第一个键为key的值,并返回其string型的值*/ 54 | string getStringValue(const string §ion,const string &key,int &ret); 55 | /*获取section段第一个键为key的值,并返回其int型的值*/ 56 | int getIntValue(const string §ion,const string &key,int &ret); 57 | /*获取section段第一个键为key的值,并返回其double型的值*/ 58 | double getDoubleValue(const string §ion,const string &key,int &ret); 59 | 60 | /*获取section段第一个键为key的值,并将值赋到value中*/ 61 | int getValue(const string §ion,const string &key,string &value); 62 | /*获取section段第一个键为key的值,并将值赋到value中,将注释赋到comment中*/ 63 | int getValue(const string §ion,const string &key,string &value,string &comment); 64 | 65 | /*获取section段所有键为key的值,并将值赋到values的vector中*/ 66 | int getValues(const string §ion,const string &key,vector &values); 67 | /*获取section段所有键为key的值,并将值赋到values的vector中,,将注释赋到comments的vector中*/ 68 | int getValues(const string §ion,const string &key,vector &value,vector &comments); 69 | 70 | bool hasSection(const string §ion) ; 71 | bool hasKey(const string §ion,const string &key) ; 72 | 73 | /* 获取section段的注释 */ 74 | int getSectionComment(const string §ion,string & comment); 75 | /* 设置section段的注释 */ 76 | int setSectionComment(const string §ion,const string & comment); 77 | /*获取注释标记符列表*/ 78 | void getCommentFlags(vector &flags); 79 | /*设置注释标记符列表*/ 80 | void setCommentFlags(const vector &flags); 81 | 82 | /*同时设置值和注释*/ 83 | int setValue(const string §ion,const string &key,const string &value,const string &comment=""); 84 | /*删除段*/ 85 | void deleteSection(const string §ion); 86 | /*删除特定段的特定参数*/ 87 | void deleteKey(const string §ion,const string &key); 88 | private: 89 | IniSection *getSection(const string §ion=""); 90 | void release(); 91 | int getline(string &str,FILE *fp); 92 | bool isComment(const string &str); 93 | bool parse(const string &content,string &key,string &value,char c= '='); 94 | //for dubug 95 | void print(); 96 | private: 97 | map sections_; 98 | string fname_; 99 | vector flags_; 100 | }; 101 | 102 | } 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /Config/stringutil.cpp: -------------------------------------------------------------------------------- 1 | #ifndef _STRINGUTIL_CPP 2 | #define _STRINGUTIL_CPP 3 | 4 | #include 5 | #include 6 | #include "stringutil.h" 7 | namespace stringutil 8 | { 9 | void trimleft(string &str,char c/*=' '*/) 10 | { 11 | //trim head 12 | 13 | int len = str.length(); 14 | 15 | int i = 0; 16 | while(str[i] == c && str[i] != '\0'){ 17 | i++; 18 | } 19 | if(i != 0){ 20 | str = string(str,i,len-i); 21 | } 22 | } 23 | 24 | void trimright(string &str,char c/*=' '*/) 25 | { 26 | //trim tail 27 | int i = 0; 28 | int len = str.length(); 29 | 30 | 31 | for(i = len - 1; i >= 0; --i ){ 32 | if(str[i] != c){ 33 | break; 34 | } 35 | } 36 | 37 | str = string(str,0,i+1); 38 | } 39 | 40 | void trim(string &str) 41 | { 42 | //trim head 43 | 44 | int len = str.length(); 45 | 46 | int i = 0; 47 | while(isspace(str[i]) && str[i] != '\0'){ 48 | i++; 49 | } 50 | if(i != 0){ 51 | str = string(str,i,len-i); 52 | } 53 | 54 | //trim tail 55 | len = str.length(); 56 | 57 | for(i = len - 1; i >= 0; --i ){ 58 | if(!isspace(str[i])){ 59 | break; 60 | } 61 | } 62 | str = string(str,0,i+1); 63 | } 64 | }//end of namespace stringutil 65 | #endif 66 | -------------------------------------------------------------------------------- /Config/stringutil.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRINGUTIL_H 2 | #define _STRINGUTIL_H 3 | 4 | #include 5 | using namespace std; 6 | 7 | namespace stringutil 8 | { 9 | /*去掉str后面的c字符*/ 10 | void trimleft(string &str,char c=' '); 11 | /*去掉str前面的c字符*/ 12 | void trimright(string &str,char c=' '); 13 | /*去掉str前面和后面的空格符,Tab符等空白符*/ 14 | void trim(string &str); 15 | /*将字符串str按分割符delim分割成多个子串*/ 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Config/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "inifile.h" 3 | #include"zookeeper.h" 4 | #include"zookeeper_log.h" 5 | 6 | 7 | using namespace std; 8 | using namespace inifile; 9 | 10 | int g_reset = 0; 11 | char g_host[512] = "172.17.0.36:2181"; 12 | char g_filepath[512] = "/Conf/test.ini"; 13 | /**********unitl*********************/ 14 | void print_usage() 15 | { 16 | printf("Usage : [testcase] [-h] [-m] [-s ip:port] \n"); 17 | printf(" -h Show help\n"); 18 | printf(" -p set the path of config data\n"); 19 | printf(" -s server ip:port\n"); 20 | printf(" -r retset data \n"); 21 | printf("For example:\n"); 22 | printf(">cat test.ini | testcase -r -p/Conf/test.ini -s172.17.0.36:2181\n"); 23 | printf(" put test.ini to zookeeper server\n"); 24 | printf(">testcase -p/Conf/test.ini -s172.17.0.36:2181 \n"); 25 | printf(" get config data from zookeeper server\n"); 26 | } 27 | 28 | void get_option(int argc,const char* argv[]) 29 | { 30 | extern char *optarg; 31 | int optch; 32 | int dem = 1; 33 | const char optstring[] = "hrps:"; 34 | 35 | 36 | while((optch = getopt(argc , (char * const *)argv , optstring)) != -1 ) 37 | { 38 | switch( optch ) 39 | { 40 | case 'h': 41 | print_usage(); 42 | exit(-1); 43 | case '?': 44 | print_usage(); 45 | printf("unknown parameter: %c\n", optopt); 46 | exit(-1); 47 | case ':': 48 | print_usage(); 49 | printf("need parameter: %c\n", optopt); 50 | exit(-1); 51 | case 'r': 52 | g_reset = 1; 53 | break; 54 | case 's': 55 | strncpy(g_host,optarg,sizeof(g_host)); 56 | break; 57 | case 'p': 58 | strncpy(g_filepath,optarg,sizeof(g_filepath)); 59 | break; 60 | default: 61 | break; 62 | } 63 | } 64 | } 65 | int setdata(const char *host,const char * filepath,const char *data) 66 | { 67 | 68 | int timeout = 30000; 69 | char path_buffer[512]; 70 | int bufferlen=sizeof(path_buffer); 71 | char conf_data[2048]; 72 | int conf_len=sizeof(conf_data); 73 | 74 | zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); //设置日志级别,避免出现一些其他信息 75 | 76 | zhandle_t* zkhandle = zookeeper_init(host,NULL, timeout, 0, (char *)"Config Test", 0); 77 | 78 | if (zkhandle ==NULL) 79 | { 80 | fprintf(stderr, "Error when connecting to zookeeper servers...\n"); 81 | exit(EXIT_FAILURE); 82 | } 83 | int ret = zoo_exists(zkhandle,filepath,0,NULL); 84 | if(ret != ZOK){ 85 | ret = zoo_create(zkhandle,filepath,data,strlen(data),NULL,0,path_buffer,bufferlen); 86 | if(ret != ZOK){ 87 | fprintf(stderr, "Error when create path :%s\n",filepath); 88 | exit(EXIT_FAILURE); 89 | } 90 | } 91 | 92 | ret = zoo_set(zkhandle,filepath,data,strlen(data),-1); 93 | if(ret != ZOK){ 94 | fprintf(stderr,"failed to set the data of path %s!\n",filepath); 95 | } 96 | 97 | zookeeper_close(zkhandle); 98 | } 99 | int main(int argc,const char *argv[]) 100 | { 101 | get_option(argc,argv); 102 | 103 | /**set data**/ 104 | /** -r **/ 105 | if(g_reset == 1){ 106 | string s; 107 | string in_data; 108 | while(cin>>s){ 109 | in_data += s + "\n"; 110 | } 111 | cout<<"in_data:"< 2 | #include 3 | #include 4 | #include"zookeeper.h" 5 | #include"zookeeper_log.h" 6 | 7 | char g_host[512]= "172.17.0.36:2181"; 8 | char g_path[512]= "/Lock"; 9 | 10 | typedef struct Lock 11 | { 12 | char lockpath[1024]; 13 | char selfpath[1024]; 14 | }Lock; 15 | 16 | void print_usage(); 17 | void get_option(int argc,const char* argv[]); 18 | 19 | /**********unitl*********************/ 20 | void print_usage() 21 | { 22 | printf("Usage : [mylock] [-h] [-p path][-s ip:port] \n"); 23 | printf(" -h Show help\n"); 24 | printf(" -p lock path\n"); 25 | printf(" -s zookeeper server ip:port\n"); 26 | printf("For example:\n"); 27 | printf(" mylock -s172.17.0.36:2181 -p /Lock\n"); 28 | } 29 | 30 | void get_option(int argc,const char* argv[]) 31 | { 32 | extern char *optarg; 33 | int optch; 34 | int dem = 1; 35 | const char optstring[] = "hp:s:"; 36 | 37 | 38 | while((optch = getopt(argc , (char * const *)argv , optstring)) != -1 ) 39 | { 40 | switch( optch ) 41 | { 42 | case 'h': 43 | print_usage(); 44 | exit(-1); 45 | case '?': 46 | print_usage(); 47 | printf("unknown parameter: %c\n", optopt); 48 | exit(-1); 49 | case ':': 50 | print_usage(); 51 | printf("need parameter: %c\n", optopt); 52 | exit(-1); 53 | case 's': 54 | strncpy(g_host,optarg,sizeof(g_host)); 55 | break; 56 | case 'p': 57 | strncpy(g_path,optarg,sizeof(g_path)); 58 | break; 59 | default: 60 | break; 61 | } 62 | } 63 | } 64 | 65 | Lock *create_lock(zhandle_t *zkhandle,const char *path) 66 | { 67 | char path_buffer[512]={0}; 68 | int bufferlen = sizeof(path_buffer); 69 | Lock * lock = NULL; 70 | 71 | int ret = zoo_exists(zkhandle,path,0,NULL); 72 | if(ret != ZOK){ 73 | ret = zoo_create(zkhandle,path,"1.0",strlen("1.0"), 74 | &ZOO_OPEN_ACL_UNSAFE,0, 75 | path_buffer,bufferlen); 76 | if(ret != ZOK){ 77 | fprintf(stderr,"failed to create the path %s!\n",path); 78 | }else{ 79 | printf("create path %s successfully!\n",path); 80 | } 81 | } 82 | if(ret == ZOK){ 83 | char child_path[512]; 84 | sprintf(child_path,"%s/lock-",path); 85 | ret = zoo_create(zkhandle,child_path,"1.0",strlen("1.0"), 86 | &ZOO_OPEN_ACL_UNSAFE,ZOO_SEQUENCE|ZOO_EPHEMERAL, 87 | path_buffer,bufferlen); 88 | if(ret != ZOK){ 89 | fprintf(stderr,"failed to create the path %s!\n",path); 90 | }else{ 91 | printf("create path %s successfully!\n",path); 92 | } 93 | } 94 | if(ret == ZOK){ 95 | lock = (Lock *)malloc(sizeof(Lock)); 96 | 97 | strcpy(lock->lockpath,path); 98 | strcpy(lock->selfpath,path_buffer); 99 | } 100 | 101 | return lock; 102 | } 103 | 104 | int try_lock(zhandle_t *zkhandle,Lock *lock) 105 | { 106 | struct String_vector children; 107 | int i = 0; 108 | int ret = zoo_get_children(zkhandle,lock->lockpath,0,&children); 109 | 110 | if(ret != ZOK){ 111 | fprintf(stderr,"error when get children of path %s\n",lock->lockpath); 112 | ret = -1; 113 | }else{ 114 | char *myseq = rindex(lock->selfpath,'/'); 115 | if (myseq != NULL) myseq += 1; 116 | 117 | ret = 1; 118 | for(i = 0; i < children.count; ++i){ 119 | if(strcmp(children.data[i],myseq) < 0){ 120 | ret = 0; 121 | break; 122 | } 123 | } 124 | 125 | for(i = 0; i < children.count; ++i){ 126 | free(children.data[i]); 127 | children.data[i] = NULL; 128 | } 129 | } 130 | 131 | return ret; 132 | } 133 | 134 | Lock *lock(zhandle_t *zkhandle,const char *path) 135 | { 136 | int ret ; 137 | Lock *lock = create_lock(zkhandle,path); 138 | if(lock != NULL){ 139 | while((ret = try_lock(zkhandle,lock)) == 0){ 140 | sleep(1); 141 | } 142 | }else{ 143 | fprintf(stderr,"error when create lock %s.\n",path); 144 | } 145 | 146 | return lock; 147 | } 148 | 149 | int unlock(zhandle_t *zkhandle,Lock * *lock) 150 | { 151 | if(*lock){ 152 | int ret = zoo_delete(zkhandle,(*lock)->selfpath,-1); 153 | if(ret != ZOK){ 154 | fprintf(stderr,"error when release lock %s.\n",(*lock)->selfpath); 155 | } 156 | free(*lock); 157 | *lock = NULL; 158 | 159 | return ret; 160 | } 161 | 162 | return ZOK; 163 | } 164 | 165 | int main(int argc, const char *argv[]) 166 | { 167 | int timeout = 30000; 168 | char path_buffer[512]; 169 | int bufferlen=sizeof(path_buffer); 170 | 171 | zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); //设置日志级别,避免出现一些其他信息 172 | 173 | get_option(argc,argv); 174 | 175 | zhandle_t* zkhandle = zookeeper_init(g_host,NULL, timeout, 0, (char *)"lock Test", 0); 176 | 177 | if (zkhandle ==NULL) 178 | { 179 | fprintf(stderr, "Error when connecting to zookeeper servers...\n"); 180 | exit(EXIT_FAILURE); 181 | } 182 | 183 | int ret = zoo_exists(zkhandle,g_path,0,NULL); 184 | if(ret != ZOK){ 185 | ret = zoo_create(zkhandle,g_path,"1.0",strlen("1.0"), 186 | &ZOO_OPEN_ACL_UNSAFE,0, 187 | path_buffer,bufferlen); 188 | if(ret != ZOK){ 189 | fprintf(stderr,"failed to create the path %s!\n",g_path); 190 | }else{ 191 | printf("create path %s successfully!\n",g_path); 192 | } 193 | } 194 | 195 | if(ret == ZOK ){ 196 | Lock *mylock = lock(zkhandle,g_path); 197 | 198 | if(mylock){ 199 | printf("get lock of %s.\n",g_path); 200 | printf("self path is %s.\n",mylock->selfpath); 201 | 202 | printf("do something....\n"); 203 | getchar(); 204 | 205 | unlock(zkhandle,&mylock); 206 | } 207 | } 208 | 209 | zookeeper_close(zkhandle); 210 | 211 | return 0; 212 | } 213 | -------------------------------------------------------------------------------- /NameService/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-g 3 | ZOOKEEPER_INSTALL=/usr/local 4 | ZOOKEEPER_INC=-I${ZOOKEEPER_INSTALL}/include/zookeeper 5 | ZOOKEEPER_LIB= -L${ZOOKEEPER_INSTALL}/lib -lzookeeper_mt 6 | 7 | APP=nameservice 8 | all: 9 | ${CC} nameservice.c -DTHREAD ${CFLAGS} ${ZOOKEEPER_INC} ${ZOOKEEPER_LIB} -o ${APP} 10 | clean: 11 | rm -f ${APP} 12 | -------------------------------------------------------------------------------- /NameService/nameservice.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include"zookeeper.h" 8 | #include"zookeeper_log.h" 9 | 10 | enum MODE{PROVIDER_MODE,CONSUMER_MODE,MONITOR_MODE} g_mode; 11 | char g_host[512]= "172.17.0.36:2181"; 12 | char g_service[512]={ 0 }; 13 | char g_path[512]="/NameService"; 14 | 15 | //watch function when child list changed 16 | void zktest_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx); 17 | //show all process ip:pid 18 | void show_list(zhandle_t *zkhandle,const char *path); 19 | //if success,the g_mode will become MODE_MONITOR 20 | void choose_mater(zhandle_t *zkhandle,const char *path); 21 | //get localhost ip:pid 22 | void getlocalhost(char *ip_pid,int len); 23 | 24 | void print_usage(); 25 | void get_option(int argc,const char* argv[]); 26 | 27 | /**********unitl*********************/ 28 | void print_usage() 29 | { 30 | printf("Usage : [nameservice] [-h] [-m mode] [-n servicename] [-s ip:port] \n"); 31 | printf(" -h Show help\n"); 32 | printf(" -m set mode:provider,consumer,monitor\n"); 33 | printf(" -n set servicename\n"); 34 | printf(" -s server ip:port\n"); 35 | printf("For example:\n"); 36 | printf(" nameservice -m provider -n query_bill -s172.17.0.36:2181 \n"); 37 | printf(" nameservice -m consumer -n query_bill -s172.17.0.36:2181 \n"); 38 | printf(" nameservice -m monitor -n query_bill -s172.17.0.36:2181 \n"); 39 | } 40 | 41 | void get_option(int argc,const char* argv[]) 42 | { 43 | extern char *optarg; 44 | int optch; 45 | int dem = 1; 46 | const char optstring[] = "hm:n:s:"; 47 | 48 | 49 | while((optch = getopt(argc , (char * const *)argv , optstring)) != -1 ) 50 | { 51 | switch( optch ) 52 | { 53 | case 'h': 54 | print_usage(); 55 | exit(-1); 56 | case '?': 57 | print_usage(); 58 | printf("unknown parameter: %c\n", optopt); 59 | exit(-1); 60 | case ':': 61 | print_usage(); 62 | printf("need parameter: %c\n", optopt); 63 | exit(-1); 64 | case 'm': 65 | if (strcasecmp(optarg,"provider") == 0){ 66 | g_mode = PROVIDER_MODE; 67 | }else if (strcasecmp(optarg,"consumer") == 0){ 68 | g_mode = CONSUMER_MODE; 69 | }else{ 70 | g_mode = MONITOR_MODE; 71 | } 72 | break; 73 | case 'n': 74 | strncpy(g_service,optarg,sizeof(g_service)); 75 | break; 76 | case 's': 77 | strncpy(g_host,optarg,sizeof(g_host)); 78 | break; 79 | default: 80 | break; 81 | } 82 | } 83 | } 84 | void zktest_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx) 85 | { 86 | /* 87 | printf("watcher event\n"); 88 | printf("type: %d\n", type); 89 | printf("state: %d\n", state); 90 | printf("path: %s\n", path); 91 | printf("watcherCtx: %s\n", (char *)watcherCtx); 92 | */ 93 | 94 | if(type == ZOO_CHILD_EVENT && 95 | state == ZOO_CONNECTED_STATE && 96 | g_mode == CONSUMER_MODE){ 97 | 98 | printf("providers list changed!\n"); 99 | show_list(zh,path); 100 | }else if(type == ZOO_CHILD_EVENT && 101 | state == ZOO_CONNECTED_STATE && 102 | g_mode == MONITOR_MODE){ 103 | 104 | printf("providers or consumers list changed!\n"); 105 | 106 | char child_path[512]; 107 | printf("providers:\n"); 108 | sprintf(child_path,"%s/%s/provider",g_path,g_service); 109 | show_list(zh,child_path); 110 | 111 | printf("consumers:\n"); 112 | sprintf(child_path,"%s/%s/consumer",g_path,g_service); 113 | show_list(zh,child_path); 114 | } 115 | } 116 | void getlocalhost(char *ip_pid,int len) 117 | { 118 | char hostname[64] = {0}; 119 | struct hostent *hent ; 120 | 121 | gethostname(hostname,sizeof(hostname)); 122 | hent = gethostbyname(hostname); 123 | 124 | char * localhost = inet_ntoa(*((struct in_addr*)(hent->h_addr_list[0]))); 125 | 126 | snprintf(ip_pid,len,"%s:%d",localhost,getpid()); 127 | } 128 | 129 | void show_list(zhandle_t *zkhandle,const char *path) 130 | { 131 | 132 | struct String_vector procs; 133 | int i = 0; 134 | char localhost[512]={0}; 135 | 136 | getlocalhost(localhost,sizeof(localhost)); 137 | 138 | int ret = zoo_get_children(zkhandle,path,1,&procs); 139 | 140 | if(ret != ZOK){ 141 | fprintf(stderr,"failed to get the children of path %s!\n",path); 142 | }else{ 143 | char child_path[512] ={0}; 144 | char ip_pid[64] = {0}; 145 | int ip_pid_len = sizeof(ip_pid); 146 | printf("--------------\n"); 147 | printf("ip\tpid\n"); 148 | for(i = 0; i < procs.count; ++i){ 149 | sprintf(child_path,"%s/%s",path,procs.data[i]); 150 | //printf("%s\n",child_path); 151 | ret = zoo_get(zkhandle,child_path,0,ip_pid,&ip_pid_len,NULL); 152 | if(ret != ZOK){ 153 | fprintf(stderr,"failed to get the data of path %s!\n",child_path); 154 | }else if(strcmp(ip_pid,localhost)==0){ 155 | printf("%s(Master)\n",ip_pid); 156 | }else{ 157 | printf("%s\n",ip_pid); 158 | } 159 | } 160 | } 161 | 162 | for(i = 0; i < procs.count; ++i){ 163 | free(procs.data[i]); 164 | procs.data[i] = NULL; 165 | } 166 | } 167 | int create(zhandle_t *zkhandle,const char *path,const char *ctx,int flag) 168 | { 169 | char path_buffer[512]; 170 | int bufferlen=sizeof(path_buffer); 171 | 172 | int ret = zoo_exists(zkhandle,path,0,NULL); 173 | if(ret != ZOK){ 174 | ret = zoo_create(zkhandle,path,ctx,strlen(ctx), 175 | &ZOO_OPEN_ACL_UNSAFE,flag, 176 | path_buffer,bufferlen); 177 | if(ret != ZOK){ 178 | fprintf(stderr,"failed to create the path %s!\n",path); 179 | }else{ 180 | printf("create path %s successfully!\n",path); 181 | } 182 | } 183 | 184 | return ZOK; 185 | } 186 | 187 | int main(int argc, const char *argv[]) 188 | { 189 | int timeout = 30000; 190 | char path_buffer[512]; 191 | int bufferlen=sizeof(path_buffer); 192 | int ret = 0; 193 | zoo_set_debug_level(ZOO_LOG_LEVEL_ERROR); //设置日志级别,避免出现一些其他信息 194 | 195 | get_option(argc,argv); 196 | 197 | zhandle_t* zkhandle = zookeeper_init(g_host,zktest_watcher_g, timeout, 0, (char *)"NameService Test", 0); 198 | 199 | if (zkhandle ==NULL) 200 | { 201 | fprintf(stderr, "Error when connecting to zookeeper servers...\n"); 202 | exit(EXIT_FAILURE); 203 | } 204 | 205 | create(zkhandle,g_path,"NameService Test",0); 206 | 207 | sprintf(path_buffer,"%s/%s",g_path,g_service); 208 | create(zkhandle,path_buffer,"NameService Test",0); 209 | 210 | sprintf(path_buffer,"%s/%s/provider",g_path,g_service); 211 | create(zkhandle,path_buffer,"NameService Test",0); 212 | 213 | sprintf(path_buffer,"%s/%s/consumer",g_path,g_service); 214 | create(zkhandle,path_buffer,"NameService Test",0); 215 | 216 | if(g_mode == PROVIDER_MODE){ 217 | 218 | char localhost[512]={0}; 219 | getlocalhost(localhost,sizeof(localhost)); 220 | 221 | char child_path[512]; 222 | sprintf(child_path,"%s/%s/provider/",g_path,g_service); 223 | ret = zoo_create(zkhandle,child_path,localhost,strlen(localhost), 224 | &ZOO_OPEN_ACL_UNSAFE,ZOO_SEQUENCE|ZOO_EPHEMERAL, 225 | path_buffer,bufferlen); 226 | if(ret != ZOK){ 227 | fprintf(stderr,"failed to create the child_path %s,buffer:%s!\n",child_path,path_buffer); 228 | }else{ 229 | printf("create child path %s successfully!\n",path_buffer); 230 | } 231 | 232 | }else if (g_mode == CONSUMER_MODE){ 233 | 234 | char localhost[512]={0}; 235 | getlocalhost(localhost,sizeof(localhost)); 236 | 237 | char child_path[512]; 238 | sprintf(child_path,"%s/%s/consumer/",g_path,g_service); 239 | ret = zoo_create(zkhandle,child_path,localhost,strlen(localhost), 240 | &ZOO_OPEN_ACL_UNSAFE,ZOO_SEQUENCE|ZOO_EPHEMERAL, 241 | path_buffer,bufferlen); 242 | if(ret != ZOK){ 243 | fprintf(stderr,"failed to create the child_path %s,buffer:%s!\n",child_path,path_buffer); 244 | }else{ 245 | printf("create child path %s successfully!\n",path_buffer); 246 | } 247 | 248 | sprintf(child_path,"%s/%s/provider",g_path,g_service); 249 | show_list(zkhandle,child_path); 250 | 251 | }else if(g_mode == MONITOR_MODE){ 252 | char child_path[512]; 253 | printf("providers:\n"); 254 | sprintf(child_path,"%s/%s/provider",g_path,g_service); 255 | show_list(zkhandle,child_path); 256 | 257 | printf("consumers:\n"); 258 | sprintf(child_path,"%s/%s/consumer",g_path,g_service); 259 | show_list(zkhandle,child_path); 260 | } 261 | 262 | getchar(); 263 | 264 | zookeeper_close(zkhandle); 265 | 266 | return 0; 267 | } 268 | -------------------------------------------------------------------------------- /Notify/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | HOME=/home/chenxueyou 3 | CFLAGS=-g 4 | ZOOKEEPER_INC=-I${HOME}/zookeeper/include/zookeeper 5 | ZOOKEEPER_LIB= -L${HOME}/zookeeper/lib -lzookeeper_mt 6 | 7 | APP=notify 8 | all: 9 | ${CC} notify.c -DTHREAD ${CFLAGS} ${ZOOKEEPER_INC} ${ZOOKEEPER_LIB} -o ${APP} 10 | clean: 11 | rm -f ${APP} 12 | -------------------------------------------------------------------------------- /Notify/notify.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"zookeeper.h" 5 | #include"zookeeper_log.h" 6 | 7 | char g_host[512]= "172.17.0.36:2181"; 8 | char g_path[512]= "/Notify"; 9 | int g_monitor_child = 0; 10 | 11 | //watch function when child list changed 12 | void zktest_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx); 13 | void show_notify(zhandle_t *zkhandle,const char *path); 14 | //show all process ip:pid 15 | void show_list(zhandle_t *zkhandle,const char *path); 16 | 17 | void print_usage(); 18 | void get_option(int argc,const char* argv[]); 19 | 20 | /**********unitl*********************/ 21 | void print_usage() 22 | { 23 | printf("Usage : [notify] [-h] [-c] [-p path][-s ip:port] \n"); 24 | printf(" -h Show help\n"); 25 | printf(" -p path\n"); 26 | printf(" -c monitor the child nodes\n"); 27 | printf(" -s zookeeper server ip:port\n"); 28 | printf("For example:\n"); 29 | printf("notify -s172.17.0.36:2181 -p /Notify\n"); 30 | } 31 | 32 | void get_option(int argc,const char* argv[]) 33 | { 34 | extern char *optarg; 35 | int optch; 36 | int dem = 1; 37 | const char optstring[] = "hcp:s:"; 38 | 39 | 40 | while((optch = getopt(argc , (char * const *)argv , optstring)) != -1 ) 41 | { 42 | switch( optch ) 43 | { 44 | case 'h': 45 | print_usage(); 46 | exit(-1); 47 | case '?': 48 | print_usage(); 49 | printf("unknown parameter: %c\n", optopt); 50 | exit(-1); 51 | case ':': 52 | print_usage(); 53 | printf("need parameter: %c\n", optopt); 54 | exit(-1); 55 | case 'c': 56 | g_monitor_child = 1; 57 | break; 58 | case 's': 59 | strncpy(g_host,optarg,sizeof(g_host)); 60 | break; 61 | case 'p': 62 | strncpy(g_path,optarg,sizeof(g_path)); 63 | break; 64 | default: 65 | break; 66 | } 67 | } 68 | } 69 | void zktest_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx) 70 | { 71 | /* 72 | printf("watcher event\n"); 73 | printf("type: %d\n", type); 74 | printf("state: %d\n", state); 75 | printf("path: %s\n", path); 76 | printf("watcherCtx: %s\n", (char *)watcherCtx); 77 | */ 78 | 79 | if(type == ZOO_CHANGED_EVENT && 80 | state == ZOO_CONNECTED_STATE && 81 | g_monitor_child == 0){ 82 | 83 | show_notify(zh,g_path); 84 | }else if(type == ZOO_CHILD_EVENT && 85 | state == ZOO_CONNECTED_STATE && 86 | g_monitor_child == 1){ 87 | 88 | show_list(zh,g_path); 89 | }else if(type == ZOO_CHANGED_EVENT && 90 | state == ZOO_CONNECTED_STATE && 91 | g_monitor_child == 1){ 92 | 93 | show_list(zh,g_path); 94 | } 95 | } 96 | void show_notify(zhandle_t *zkhandle,const char *path) 97 | { 98 | char notify_buffer[1024]={0}; 99 | int notify_len = sizeof(notify_buffer); 100 | 101 | int ret = zoo_get(zkhandle,g_path,1,notify_buffer,¬ify_len,NULL); 102 | if(ret != ZOK){ 103 | fprintf(stderr,"failed to get the data of path %s!\n",g_path); 104 | }else{ 105 | printf("Notice:%s\n",notify_buffer); 106 | } 107 | } 108 | void show_list(zhandle_t *zkhandle,const char *path) 109 | { 110 | 111 | struct String_vector children; 112 | int i = 0; 113 | int ret = zoo_get_children(zkhandle,path,1,&children); 114 | 115 | if(ret == ZOK){ 116 | char child_path[512] ={0}; 117 | char notify_buffer[1024] = {0}; 118 | int notify_len = sizeof(notify_buffer); 119 | 120 | printf("--------------\n"); 121 | for(i = 0; i < children.count; ++i){ 122 | sprintf(child_path,"%s/%s",g_path,children.data[i]); 123 | ret = zoo_get(zkhandle,child_path,1,notify_buffer,¬ify_len,NULL); 124 | if(ret != ZOK){ 125 | fprintf(stderr,"failed to get the data of path %s!\n",child_path); 126 | }else{ 127 | printf("%s:%s\n",children.data[i],notify_buffer); 128 | } 129 | } 130 | }else{ 131 | fprintf(stderr,"failed to get the children of path %s!\n",path); 132 | } 133 | 134 | for(i = 0; i < children.count; ++i){ 135 | free(children.data[i]); 136 | children.data[i] = NULL; 137 | } 138 | } 139 | 140 | int main(int argc, const char *argv[]) 141 | { 142 | int timeout = 30000; 143 | char path_buffer[512]; 144 | int bufferlen=sizeof(path_buffer); 145 | 146 | zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); //设置日志级别,避免出现一些其他信息 147 | 148 | get_option(argc,argv); 149 | 150 | zhandle_t* zkhandle = zookeeper_init(g_host,zktest_watcher_g, timeout, 0, (char *)"Notify Test", 0); 151 | 152 | if (zkhandle ==NULL) 153 | { 154 | fprintf(stderr, "Error when connecting to zookeeper servers...\n"); 155 | exit(EXIT_FAILURE); 156 | } 157 | 158 | int ret = zoo_exists(zkhandle,g_path,0,NULL); 159 | if(ret != ZOK){ 160 | ret = zoo_create(zkhandle,g_path,"1.0",strlen("1.0"), 161 | &ZOO_OPEN_ACL_UNSAFE,0, 162 | path_buffer,bufferlen); 163 | if(ret != ZOK){ 164 | fprintf(stderr,"failed to create the path %s!\n",g_path); 165 | }else{ 166 | printf("create path %s successfully!\n",g_path); 167 | } 168 | } 169 | 170 | if(ret == ZOK && g_monitor_child == 0){ 171 | show_notify(zkhandle,g_path); 172 | }else if(ret == ZOK && g_monitor_child == 1){ 173 | show_list(zkhandle,g_path); 174 | } 175 | 176 | getchar(); 177 | 178 | zookeeper_close(zkhandle); 179 | 180 | return 0; 181 | } 182 | -------------------------------------------------------------------------------- /Queue/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | HOME=/home/chenxueyou 3 | CFLAGS=-g 4 | ZOOKEEPER_INC=-I${HOME}/zookeeper/include/zookeeper 5 | ZOOKEEPER_LIB= -L${HOME}/zookeeper/lib -lzookeeper_mt 6 | 7 | APP=myqueue 8 | all: 9 | ${CC} queue.c -DTHREAD ${CFLAGS} ${ZOOKEEPER_INC} ${ZOOKEEPER_LIB} -o ${APP} 10 | clean: 11 | rm -f ${APP} 12 | -------------------------------------------------------------------------------- /Queue/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"zookeeper.h" 5 | #include"zookeeper_log.h" 6 | 7 | char g_host[512]= "172.17.0.36:2181"; 8 | char g_path[512]= "/Queue"; 9 | char g_value[512]="msg"; 10 | enum MODE{PUSH_MODE,POP_MODE} g_mode; 11 | 12 | void print_usage(); 13 | void get_option(int argc,const char* argv[]); 14 | 15 | /**********unitl*********************/ 16 | void print_usage() 17 | { 18 | printf("Usage : [myqueue] [-h] [-m mode] [-p path ] [-v value][-s ip:port] \n"); 19 | printf(" -h Show help\n"); 20 | printf(" -p Queue path\n"); 21 | printf(" -m mode:push or pop\n"); 22 | printf(" -v the value you want to push\n"); 23 | printf(" -s zookeeper server ip:port\n"); 24 | printf("For example:\n"); 25 | printf(" push the message \"Hello\" into the queue Queue:\n"); 26 | printf(" >myqueue -s172.17.0.36:2181 -p /Queue -m push -v Hello\n"); 27 | printf(" pop one message from the queue Queue:\n"); 28 | printf(" >myqueue -s172.17.0.36:2181 -p /Queue -m pop\n"); 29 | } 30 | 31 | void get_option(int argc,const char* argv[]) 32 | { 33 | extern char *optarg; 34 | int optch; 35 | int dem = 1; 36 | const char optstring[] = "hv:m:p:s:"; 37 | 38 | 39 | g_mode = PUSH_MODE; 40 | while((optch = getopt(argc , (char * const *)argv , optstring)) != -1 ) 41 | { 42 | switch( optch ) 43 | { 44 | case 'h': 45 | print_usage(); 46 | exit(-1); 47 | case '?': 48 | print_usage(); 49 | printf("unknown parameter: %c\n", optopt); 50 | exit(-1); 51 | case ':': 52 | print_usage(); 53 | printf("need parameter: %c\n", optopt); 54 | exit(-1); 55 | case 'm': 56 | if(strcasecmp(optarg,"push")==0){ 57 | g_mode = PUSH_MODE; 58 | }else{ 59 | g_mode = POP_MODE; 60 | } 61 | break; 62 | case 's': 63 | strncpy(g_host,optarg,sizeof(g_host)); 64 | break; 65 | case 'p': 66 | strncpy(g_path,optarg,sizeof(g_path)); 67 | break; 68 | case 'v': 69 | strncpy(g_value,optarg,sizeof(g_value)); 70 | break; 71 | default: 72 | break; 73 | } 74 | } 75 | } 76 | 77 | int push(zhandle_t *zkhandle,const char *path,char *element) 78 | { 79 | char child_path[512] = {0}; 80 | char path_buffer[512] = {0}; 81 | int bufferlen = sizeof(path_buffer); 82 | 83 | sprintf(child_path,"%s/queue-",path); 84 | int ret = zoo_create(zkhandle,child_path,element,strlen(element), 85 | &ZOO_OPEN_ACL_UNSAFE,ZOO_SEQUENCE, 86 | path_buffer,bufferlen); 87 | if(ret != ZOK){ 88 | fprintf(stderr,"failed to create the path %s!\n",path); 89 | }else{ 90 | printf("create path %s successfully!\n",path); 91 | } 92 | 93 | return ret; 94 | } 95 | 96 | int pop(zhandle_t *zkhandle,const char *path,char *element,int *len) 97 | { 98 | int i = 0; 99 | struct String_vector children; 100 | int ret = zoo_get_children(zkhandle,path,0,&children); 101 | 102 | 103 | if(ret != ZOK){ 104 | fprintf(stderr,"failed to create the path %s!\n",path); 105 | }else if (children.count == 0){ 106 | strcpy(element,""); 107 | *len = 0; 108 | ret = -1; 109 | }else{ 110 | char *min = children.data[0]; 111 | for(i = 0; i < children.count; ++i){ 112 | printf("%s:%s\n",min,children.data[i]); 113 | if(strcmp(min,children.data[i]) > 0){ 114 | min = children.data[i]; 115 | } 116 | } 117 | if(min != NULL){ 118 | char child_path[512]={0}; 119 | sprintf(child_path,"%s/%s",path,min); 120 | ret = zoo_get(zkhandle,child_path,0,element,len,NULL); 121 | 122 | if(ret != ZOK){ 123 | fprintf(stderr,"failed to get data of the path %s!\n",child_path); 124 | }else{ 125 | ret = zoo_delete(zkhandle,child_path, -1); 126 | 127 | if(ret != ZOK){ 128 | fprintf(stderr,"failed to delete the path %s!\n",child_path); 129 | } 130 | } 131 | } 132 | } 133 | 134 | for(i = 0; i < children.count; ++i){ 135 | free(children.data[i]); 136 | children.data[i] = NULL; 137 | } 138 | 139 | 140 | return ret; 141 | } 142 | 143 | int front(zhandle_t *zkhandle,char *path,char *element,int *len) 144 | { 145 | int i = 0; 146 | struct String_vector children; 147 | int ret = zoo_get_children(zkhandle,path,0,&children); 148 | 149 | if(ret != ZOK){ 150 | fprintf(stderr,"failed to create the path %s!\n",path); 151 | }else if(children.count == 0){ 152 | strcpy(element,""); 153 | *len = 0; 154 | ret = -1; 155 | }else{ 156 | char *min = NULL; 157 | for(i = 0; i < children.count; ++i){ 158 | if(strcmp(min,children.data[i]) > 0){ 159 | min = children.data[i]; 160 | } 161 | } 162 | if(min != NULL){ 163 | char child_path[512]={0}; 164 | sprintf(child_path,"%s/%s",path,min); 165 | ret = zoo_get(zkhandle,child_path,0,element,len,NULL); 166 | 167 | if(ret != ZOK){ 168 | fprintf(stderr,"failed to get data of the path %s!\n",child_path); 169 | } 170 | } 171 | } 172 | 173 | for(i = 0; i < children.count; ++i){ 174 | free(children.data[i]); 175 | children.data[i] = NULL; 176 | } 177 | 178 | return ret; 179 | 180 | } 181 | 182 | 183 | int main(int argc, const char *argv[]) 184 | { 185 | int timeout = 30000; 186 | char path_buffer[512]; 187 | int bufferlen=sizeof(path_buffer); 188 | 189 | zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); //设置日志级别,避免出现一些其他信息 190 | 191 | get_option(argc,argv); 192 | 193 | zhandle_t* zkhandle = zookeeper_init(g_host,NULL, timeout, 0, (char *)"lock Test", 0); 194 | 195 | if (zkhandle ==NULL) 196 | { 197 | fprintf(stderr, "Error when connecting to zookeeper servers...\n"); 198 | exit(EXIT_FAILURE); 199 | } 200 | 201 | int ret = zoo_exists(zkhandle,g_path,0,NULL); 202 | if(ret != ZOK){ 203 | ret = zoo_create(zkhandle,g_path,"1.0",strlen("1.0"), 204 | &ZOO_OPEN_ACL_UNSAFE,0, 205 | path_buffer,bufferlen); 206 | if(ret != ZOK){ 207 | fprintf(stderr,"failed to create the path %s!\n",g_path); 208 | }else{ 209 | printf("create path %s successfully!\n",g_path); 210 | } 211 | } 212 | 213 | if(g_mode == PUSH_MODE){ 214 | push(zkhandle,g_path,g_value); 215 | printf("push:%s\n",g_value); 216 | }else{ 217 | int len = sizeof(g_value); 218 | ret = pop(zkhandle,g_path,g_value,&len) ; 219 | 220 | if(ret == ZOK){ 221 | printf("pop:%s\n",g_value); 222 | }else if( ret == -1){ 223 | printf("queue is empty\n"); 224 | } 225 | } 226 | 227 | 228 | 229 | zookeeper_close(zkhandle); 230 | 231 | return 0; 232 | } 233 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ZooKeeper-Exam 2 | ============== 3 | 4 | ZooKeeper练习代码 5 | 6 | 7 | * ClusterMonitor : 集群监控和Master选举 8 | * Config : 远程配置管理,根据[inifile2](https://github.com/Winnerhust/inifile2)修改而成,主要修改了open函数,其他不变 9 | * Notify : 分布式通知/协调 10 | * NameService: 命名服务 11 | * Lock: 分布式锁 12 | * Queue: 分布式队列 13 | * mymetaq: 负载均衡,实现了生产者负载均衡,消费者负载均衡尚未完成 14 | 15 | 更多详情,请转到[我的博客](http://blog.csdn.net/qq910894904/article/details/40835105) 16 | -------------------------------------------------------------------------------- /mymetaq/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | HOME=/home/chenxueyou 3 | CFLAGS=-g 4 | ZOOKEEPER_INC=-I${HOME}/zookeeper/include/zookeeper 5 | ZOOKEEPER_LIB= -L${HOME}/zookeeper/lib -lzookeeper_mt 6 | 7 | APP=producer consumer 8 | all: 9 | ${CC} producer.c -DTHREAD ${CFLAGS} ${ZOOKEEPER_INC} ${ZOOKEEPER_LIB} -o producer 10 | ${CC} consumer.c -DTHREAD ${CFLAGS} ${ZOOKEEPER_INC} ${ZOOKEEPER_LIB} -o consumer 11 | clean: 12 | rm -f ${APP} 13 | -------------------------------------------------------------------------------- /mymetaq/consumer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include"zookeeper.h" 6 | #include"zookeeper_log.h" 7 | 8 | char g_host[512]= "172.17.0.36:2181"; 9 | char g_topic[512]= "MyTopic"; 10 | char g_my_path[512]={0}; 11 | int g_groupid = 0; 12 | enum MODE{MASTER_MODE,SLAVE_MODE} g_mode; 13 | 14 | void print_usage(); 15 | void get_option(int argc,const char* argv[]); 16 | 17 | /**********unitl*********************/ 18 | void print_usage() 19 | { 20 | printf("Usage : [consumer] [-h] [-t topic] [-g groudid ] [-s ip:port] \n"); 21 | printf(" -h Show help\n"); 22 | printf(" -t topic name\n"); 23 | printf(" -g groupid\n"); 24 | printf(" -s zookeeper server ip:port\n"); 25 | printf("For example:\n"); 26 | printf(" recive the message from the breaker:\n"); 27 | printf(" >consumer -t MyTopic -g 0 -s 172.17.0.36:2181\n"); 28 | } 29 | 30 | void get_option(int argc,const char* argv[]) 31 | { 32 | extern char *optarg; 33 | int optch; 34 | int dem = 1; 35 | const char optstring[] = "hg:t:s:"; 36 | 37 | 38 | while((optch = getopt(argc , (char * const *)argv , optstring)) != -1 ) 39 | { 40 | switch( optch ) 41 | { 42 | case 'h': 43 | print_usage(); 44 | exit(-1); 45 | case '?': 46 | print_usage(); 47 | printf("unknown parameter: %c\n", optopt); 48 | exit(-1); 49 | case ':': 50 | print_usage(); 51 | printf("need parameter: %c\n", optopt); 52 | exit(-1); 53 | case 's': 54 | strncpy(g_host,optarg,sizeof(g_host)); 55 | break; 56 | case 't': 57 | strncpy(g_topic,optarg,sizeof(g_topic)); 58 | break; 59 | case 'g': 60 | if(optarg){ 61 | g_groupid = atoi(optarg); 62 | } 63 | break; 64 | default: 65 | break; 66 | } 67 | } 68 | } 69 | void convert_str_to_vector(char *str,char * delim,struct String_vector *vector) 70 | { 71 | int i = 0; 72 | 73 | char *result = strsep( str,delim); 74 | while( result != NULL ) { 75 | ++i; 76 | result = strsep( str,delim ); 77 | } 78 | 79 | if(i > 0){ 80 | vector->count = i; 81 | vector->data = calloc(sizeof(*(vector->data)),vector->count); 82 | }else{ 83 | vector->count = 0; 84 | vector->data = NULL; 85 | } 86 | 87 | char *result = strsep( str,delim); 88 | i = 0; 89 | while( result != NULL ) { 90 | vector.data[i++] = strdup(result); 91 | result = strsep( str,delim ); 92 | } 93 | 94 | } 95 | void do_work(zhandle_t *zkhandle) 96 | { 97 | char group_path[512]={0}; 98 | char breaker_topic_path[512]={0}; 99 | 100 | sprintf(group_path,"/Consumer/%s/group-%d",g_topic,g_groupid); 101 | sprintf(breaker_topic_path,"/Breaker/%s",g_topic); 102 | 103 | if(g_mode == MASTER_MODE){ 104 | set_balancing_strategy(zkhandle,group_path,breaker_topic_path); 105 | }else{ 106 | //todo 107 | char str_partitions[512]={0}; 108 | int len = sizeof(str_partitions); 109 | int ret = zoo_get(zkhandle,g_my_path,zkget_watcher_g,"",str_partitions,&len,NULL); 110 | 111 | if(ret != ZOK){ 112 | fprintf(stderr,"failed to get data of the path %s.\n",g_my_path); 113 | }else{ 114 | struct String_vector partitions; 115 | 116 | convert_str_to_vector(str_partitions,",",&partitions); 117 | int i = 0; 118 | for(i = 0; i < partitions.count; ++i){ 119 | sprintf(msg_path,"/Breaker/%s/Partition-%s",g_topic,partitions.data[i]); 120 | 121 | } 122 | } 123 | 124 | } 125 | 126 | } 127 | void zkbalance_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx) 128 | { 129 | /* 130 | printf("watcher event\n"); 131 | printf("type: %d\n", type); 132 | printf("state: %d\n", state); 133 | printf("path: %s\n", path); 134 | printf("watcherCtx: %s\n", (char *)watcherCtx); 135 | */ 136 | char group_path[512]={0}; 137 | char breaker_topic_path[512]={0}; 138 | 139 | sprintf(group_path,"/Consumer/%s/group-%d",g_topic,g_groupid); 140 | sprintf(breaker_topic_path,"/Breaker/%s",g_topic); 141 | 142 | char *p_self_name = rindex(g_my_path,'/')+1; 143 | 144 | choose_mater(zkhandle,group_path,p_self_name); 145 | 146 | if(g_mode == MASTER_MODE){ 147 | set_balancing_strategy(zh,group_path,breaker_topic_path); 148 | }else{ 149 | 150 | } 151 | } 152 | 153 | void choose_mater(zhandle_t *zkhandle,const char *group_path,const char *self_name) 154 | { 155 | struct String_vector procs; 156 | int i = 0; 157 | int ret = zoo_wget_children(zkhandle,group_path,zkbalance_watcher_g,NULL,&procs); 158 | 159 | if(ret != ZOK || procs.count == 0){ 160 | fprintf(stderr,"failed to get the children of path %s!\n",group_path); 161 | }else{ 162 | char master_name[512]={0}; 163 | 164 | strcpy(master_name,procs.data[0]); 165 | 166 | for(i = 1; i < procs.count; ++i){ 167 | if(strcmp(master_name,procs.data[i])>0){ 168 | strcpy(master_name,procs.data[i]); 169 | } 170 | } 171 | 172 | if(strcmp(master_name,self_name) == 0){ 173 | g_mode = MASTER_MODE; 174 | }else{ 175 | g_mode = SLAVE_MODE; 176 | } 177 | 178 | } 179 | 180 | for(i = 0; i < procs.count; ++i){ 181 | free(procs.data[i]); 182 | procs.data[i] = NULL; 183 | } 184 | 185 | } 186 | int set_balancing_strategy(zhandle_t *zkhandle,char *group_path,char *breaker_topic_path) 187 | { 188 | if(g_mode != MASTER_MODE){ 189 | return 0; 190 | } 191 | struct String_vector partitions; 192 | struct String_vector clients; 193 | 194 | int ret = zoo_wget_children(zkhandle,breaker_topic_path,zkbalance_watcher_g,NULL,&partitions); 195 | if(ret != ZOK){ 196 | fprintf(stderr,"error when get children of path %s.\n",breaker_topic_path); 197 | return ret; 198 | } 199 | 200 | ret = zoo_wget_children(zkhandle,group_path,zkbalance_watcher_g,NULL,&clients); 201 | if(ret != ZOK){ 202 | fprintf(stderr,"error when get children of path %s.\n",group_path); 203 | return ret; 204 | } 205 | 206 | int i = 0; 207 | char client_path[512]={0}; 208 | char buffer[1024] = {0}; 209 | 210 | struct String_vector values; 211 | if(clients.count){ 212 | values.count = clients.count < partitions.count ? clients.count : partitions.count; 213 | 214 | values.data = calloc(sizeof(*values.data),values.count); 215 | memset(values.data,0,sizeof(*values.data)*values.count); 216 | }else{ 217 | values.count = 0; 218 | values.data = NULL; 219 | } 220 | printf("values.count = %d\n",values.count); 221 | 222 | for(i = 0; i < partitions.count; ++i){ 223 | int k = i % clients.count; 224 | if (values.data[k] == NULL){ 225 | sprintf(buffer,"%d",i); 226 | values.data[k] = strdup(buffer); 227 | 228 | }else { 229 | sprintf(buffer,"%s,%d",values.data[k],i); 230 | free(values.data[k]); 231 | values.data[k] = strdup(buffer); 232 | } 233 | printf("%d = %s\n",k,values.data[k]); 234 | } 235 | for(i = 0; i < values.count; ++i){ 236 | sprintf(client_path,"/Consumer/%s/group-%d/%s",g_topic,g_groupid,clients.data[i%clients.count]); 237 | 238 | ret = zoo_set(zkhandle,client_path,values.data[i],strlen(values.data[i]),-1); 239 | if(ret != ZOK){ 240 | continue; 241 | } 242 | printf("%s = %s\n",client_path,values.data[i]); 243 | 244 | free(values.data[i]); 245 | } 246 | //多余的consumer将收不到分区消息 247 | for(i = values.count; i < clients.count; ++i){ 248 | sprintf(client_path,"/Consumer/%s/group-%d/%s",g_topic,g_groupid,clients.data[i%clients.count]); 249 | 250 | ret = zoo_set(zkhandle,client_path,"",0,-1); 251 | if(ret != ZOK){ 252 | continue; 253 | } 254 | printf("%s = %s\n",client_path,""); 255 | 256 | } 257 | } 258 | 259 | //同步方式创建节点 260 | void create(zhandle_t *zkhandle,char *path,int flag,const char *ctx) 261 | { 262 | char path_buffer[512]; 263 | int bufferlen=sizeof(path_buffer); 264 | 265 | 266 | int ret = zoo_exists(zkhandle,path,0,NULL); 267 | if(ret != ZOK){ 268 | ret = zoo_create(zkhandle,path,ctx,strlen(ctx), 269 | &ZOO_OPEN_ACL_UNSAFE,flag, 270 | path_buffer,bufferlen); 271 | 272 | if (ret != ZOK){ 273 | printf("节点创建失败:%s \n",path); 274 | exit(EXIT_FAILURE); 275 | }else { 276 | printf("创建的节点名称为:%s\n",path_buffer); 277 | printf("创建的节点值为:%s\n",(char *)ctx); 278 | } 279 | }else{ 280 | printf("path:%s 已经存在,无需创建\n",path); 281 | } 282 | } 283 | 284 | 285 | int main(int argc, const char *argv[]) 286 | { 287 | int timeout = 30000; 288 | 289 | zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); //设置日志级别,避免出现一些其他信息 290 | 291 | get_option(argc,argv); 292 | 293 | zhandle_t* zkhandle = zookeeper_init(g_host,NULL, timeout, 0, (char *)"Load Balancing Test", 0); 294 | 295 | if (zkhandle ==NULL){ 296 | fprintf(stderr, "Error when connecting to zookeeper servers...\n"); 297 | exit(EXIT_FAILURE); 298 | } 299 | 300 | char consumer_path[512] = "/Consumer"; 301 | char topic_path[512] = {0}; 302 | char group_path[512] = {0}; 303 | char client_path[512] = {0}; 304 | 305 | sprintf(topic_path,"%s/%s",consumer_path,g_topic); 306 | sprintf(group_path,"%s/group-%d",topic_path,g_groupid); 307 | sprintf(client_path,"%s/client-",group_path); 308 | 309 | 310 | create(zkhandle,consumer_path,0,""); 311 | create(zkhandle,topic_path,0,""); 312 | create(zkhandle,group_path,0,"00000000"); 313 | 314 | int bufferlen = sizeof(g_my_path); 315 | 316 | int ret = zoo_create(zkhandle,client_path,NULL,0, 317 | &ZOO_OPEN_ACL_UNSAFE,ZOO_SEQUENCE|ZOO_EPHEMERAL, 318 | g_my_path,bufferlen); 319 | 320 | if (ret != ZOK){ 321 | printf("节点创建失败:%s \n",client_path); 322 | exit(EXIT_FAILURE); 323 | }else { 324 | printf("创建的节点名称为:%s\n",g_my_path); 325 | } 326 | 327 | char self_name[512] = {0}; 328 | 329 | strcpy(self_name,rindex(g_my_path,'/')+1); 330 | 331 | 332 | choose_mater(zkhandle,group_path,self_name); 333 | 334 | do_work(zkhandle); 335 | 336 | getchar(); 337 | 338 | zookeeper_close(zkhandle); 339 | 340 | return 0; 341 | } 342 | -------------------------------------------------------------------------------- /mymetaq/producer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include"zookeeper.h" 6 | #include"zookeeper_log.h" 7 | 8 | char g_host[512]= "172.17.0.36:2181"; 9 | char g_topic[512]= "MyTopic"; 10 | char g_msg[512]="Hello,World"; 11 | int g_repeated_num = 1; 12 | int g_partition_num = 4; 13 | 14 | void print_usage(); 15 | void get_option(int argc,const char* argv[]); 16 | 17 | /**********unitl*********************/ 18 | void print_usage() 19 | { 20 | printf("Usage : [produce] [-h] [-t topic] [-m msg] [-r reapted_num] [-n partition_num] [-s ip:port] \n"); 21 | printf(" -h Show help\n"); 22 | printf(" -t topic name\n"); 23 | printf(" -m the message content\n"); 24 | printf(" -r send repeated times\n"); 25 | printf(" -n default partition number\n"); 26 | printf(" -s zookeeper server ip:port\n"); 27 | printf("For example:\n"); 28 | printf(" send the message \"Hello,World\" to the breaker:\n"); 29 | printf(" >produce -t MyTopic -m Hello,World -n 3 -s 172.17.0.36:2181\n"); 30 | } 31 | 32 | void get_option(int argc,const char* argv[]) 33 | { 34 | extern char *optarg; 35 | int optch; 36 | int dem = 1; 37 | const char optstring[] = "ht:r:m:n:s:"; 38 | 39 | 40 | while((optch = getopt(argc , (char * const *)argv , optstring)) != -1 ) 41 | { 42 | switch( optch ) 43 | { 44 | case 'h': 45 | print_usage(); 46 | exit(-1); 47 | case '?': 48 | print_usage(); 49 | printf("unknown parameter: %c\n", optopt); 50 | exit(-1); 51 | case ':': 52 | print_usage(); 53 | printf("need parameter: %c\n", optopt); 54 | exit(-1); 55 | case 'm': 56 | strncpy(g_msg,optarg,sizeof(g_msg)); 57 | break; 58 | case 's': 59 | strncpy(g_host,optarg,sizeof(g_host)); 60 | break; 61 | case 't': 62 | strncpy(g_topic,optarg,sizeof(g_topic)); 63 | break; 64 | case 'r': 65 | if(optarg != NULL){ 66 | g_repeated_num = atoi(optarg); 67 | } 68 | break; 69 | case 'n': 70 | if(optarg != NULL){ 71 | g_partition_num= atoi(optarg); 72 | } 73 | break; 74 | default: 75 | break; 76 | } 77 | } 78 | } 79 | 80 | //同步方式创建节点 81 | void create(zhandle_t *zkhandle,char *path,int flag,const char *ctx) 82 | { 83 | char path_buffer[512]; 84 | int bufferlen=sizeof(path_buffer); 85 | 86 | 87 | int ret = zoo_exists(zkhandle,path,0,NULL); 88 | if(ret != ZOK){ 89 | ret = zoo_create(zkhandle,path,ctx,strlen(ctx), 90 | &ZOO_OPEN_ACL_UNSAFE,flag, 91 | path_buffer,bufferlen); 92 | 93 | if (ret != ZOK){ 94 | printf("节点创建失败:%s \n",path); 95 | exit(EXIT_FAILURE); 96 | }else { 97 | printf("创建的节点名称为:%s\n",path_buffer); 98 | printf("创建的节点值为:%s\n",(char *)ctx); 99 | } 100 | }else{ 101 | printf("path:%s 已经存在,无需创建\n",path); 102 | } 103 | } 104 | 105 | 106 | int main(int argc, const char *argv[]) 107 | { 108 | int timeout = 30000; 109 | char path_buffer[512]; 110 | int bufferlen=sizeof(path_buffer); 111 | 112 | zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); //设置日志级别,避免出现一些其他信息 113 | 114 | get_option(argc,argv); 115 | 116 | zhandle_t* zkhandle = zookeeper_init(g_host,NULL, timeout, 0, (char *)"Load Balancing Test", 0); 117 | 118 | if (zkhandle ==NULL){ 119 | fprintf(stderr, "Error when connecting to zookeeper servers...\n"); 120 | exit(EXIT_FAILURE); 121 | } 122 | 123 | char breaker_path[512] = "/Breaker"; 124 | char topic_path[512] = {0}; 125 | char partition_path[512] = {0}; 126 | 127 | sprintf(topic_path,"%s/%s",breaker_path,g_topic); 128 | 129 | //init environment 130 | create(zkhandle,breaker_path,0,""); 131 | create(zkhandle,topic_path,0,""); 132 | 133 | int i = 0; 134 | for(i = 0; i < g_partition_num ; ++i){ 135 | sprintf(partition_path,"%s/Partition-%d",topic_path,i); 136 | create(zkhandle,partition_path,0,""); 137 | } 138 | 139 | //send message by rand time 140 | srand(time(NULL)); 141 | char msg_path[512] = {0}; 142 | for(i = 0; i < g_repeated_num; ++i){ 143 | sprintf(msg_path,"%s/Partition-%d/msg-",topic_path,i % g_partition_num); 144 | // create seq msg node 145 | create(zkhandle,msg_path,ZOO_SEQUENCE,g_msg); 146 | int time = rand()%10; 147 | printf("sleep time:%d\n",time); 148 | sleep(time); 149 | } 150 | 151 | 152 | 153 | zookeeper_close(zkhandle); 154 | 155 | return 0; 156 | } 157 | --------------------------------------------------------------------------------