zk系列-c++下zookeeper使用实例

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务。分布式应用可以使用它来实现诸如:统一命名服务、配置管理、分布式锁服务、集群管理等功能。公司常用到的是Java服务集群的管理。

1.函数介绍

[cpp] 
view plain
copy

  1. //create a handle to used communicate with zookeeper
  2. zhandle_t *zookeeper_init(const char *host, watcher_fn fn, int recv_timeout, const clientid_t *clientid, void *context, int flags)
  3. //create a node synchronously
  4. int zoo_create(zhandle_t *zh, const char *path, const char *value,int valuelen,
  5. const struct ACL_vector *acl, int flags,char *path_buffer, int path_buffer_len);
  6. //lists the children of a node synchronously.
  7. int zoo_wget_children(zhandle_t *zh, const char *path, watcher_fn watcher, void* watcherCtx, struct String_vector *strings)
  8. //close the zookeeper handle and free up any resources.
  9. int zookeeper_close(zhandle_t *zh)

2.实例

用上面3个函数,就能创建一个简单的集群管理。

数据存储结构为

服务端向Zk注册服务

[cpp] 
view plain
copy

  1. //连接zk
  2. void ZkRegistry::ConnectZK() {
  3. if (zhandle_) {
  4. zookeeper_close(zhandle_);
  5. }
  6. int count = 0;
  7. do {
  8. ++count;
  9. zhandle_ = zookeeper_init(zk_hosts_.c_str(),InitWatcher, timeout_, NULL, NULL, 0);
  10. } while (!connected_ && count < ZK_MAX_CONNECT_TIMES);
  11. if (count >= ZK_MAX_CONNECT_TIMES) {
  12. SLOG_WARN("ZkRegistry::Init --> connect host " << zk_hosts_ << " over max times:" << count);
  13. return;
  14. }
  15. }
  16. //发布服务,建立临时节点
  17. void ZkRegistry::PublishService() {
  18. if (zhandle_ == NULL) {
  19. ConnectZK();
  20. }
  21. string server_path = PING_SERVER + "/" + PingConfig::instance().get_index() + "/"
  22. + GetIp() + ":" + PingConfig::instance().get_port();
  23. char res_path[128];
  24. int rc = zoo_create(zhandle_, server_path.c_str(), GetIp().c_str(), GetIp().size(),
  25. &ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL, res_path, 128);
  26. if (rc) {
  27. SLOG_INFO("ZkRegistry::PublishService --> zoo_create() path=" << server_path << "," << zerror(rc));
  28. }
  29. }
  30. //每隔10s注册一次服务
  31. void ZkRegistry::run() {
  32. while(true) {
  33. SLOG_INFO("publish service");
  34. ConnectZK();
  35. PublishService();
  36. sleep(10);
  37. }
  38. }
  39. void ZkRegistry::InitWatcher(zhandle_t *zh, int type, int state, const char *path, void *watcher_ctx) {
  40. if (state == ZOO_CONNECTED_STATE) {
  41. connected_ = true;
  42. SLOG_INFO("InitWatcher() ZOO_CONNECTED_STATE");
  43. } else if (state == ZOO_AUTH_FAILED_STATE) {
  44. SLOG_INFO("InitWatcher() ZOO_AUTH_FAILED_STATE");
  45. } else if (state == ZOO_EXPIRED_SESSION_STATE) {
  46. SLOG_INFO("InitWatcher() ZOO_EXPIRED_SESSION_STATE");
  47. } else if (state == ZOO_CONNECTING_STATE) {
  48. SLOG_INFO("InitWatcher() ZOO_CONNECTING_STATE");
  49. } else if (state == ZOO_ASSOCIATING_STATE) {
  50. SLOG_INFO("InitWatcher() ZOO_ASSOCIATING_STATE");
  51. }
  52. }

客户端获取服务列表

[cpp] 
view plain
copy

  1. //连接zk server
  2. void ZkClient::ConnectZK() {
  3. cout << "ZkClient::ConnectZK" << endl;
  4. if (zhandle_) {
  5. zookeeper_close(zhandle_);
  6. }
  7. zhandle_ = NULL;
  8. connected_ = false;
  9. int count = 0;
  10. do {
  11. ++count;
  12. zhandle_ = zookeeper_init(zk_hosts_.c_str(), InitWatcher, timeout_, NULL, NULL, 0);
  13. sleep(5 * ONE_SECONDS);
  14. } while (!connected_ && count < ZK_MAX_CONNECT_TIMES);
  15. if (count >= ZK_MAX_CONNECT_TIMES){
  16. cout << "ZkClient::Init --> connecting zookeeper host: " << zk_hosts_ << " over times: " << count << endl;
  17. }
  18. }
  19. //更新服务列表,冷备和热备
  20. void ZkClient::Update() {
  21. cout << "ZkClient::Update" << endl;
  22. if (zhandle_ == NULL || connected_ == false) {
  23. Init();
  24. }
  25. //获得服务份数
  26. struct String_vector str_vec;
  27. int ret = zoo_wget_children(zhandle_, PING_SERVER.c_str(), ServiceWatcher, NULL, &str_vec);
  28. if (ret) {
  29. cout << "Update --> read path:" << PING_SERVER << " wrong, " << zerror(ret) << endl;
  30. return;
  31. }
  32. //获得各份服务ip:port
  33. for (int i = 0; i < str_vec.count; ++i) {
  34. struct String_vector node_vec;
  35. string path = PING_SERVER + "/" + str_vec.data[i];
  36. int ret = zoo_wget_children(zhandle_, path.c_str(), ServiceWatcher, NULL, &node_vec);
  37. cout << "Update --> path:" << path << ", ret:" << ret << ", node‘s size:" << node_vec.count << endl;
  38. if (ret || node_vec.count != 1) {
  39. continue;
  40. }
  41. ....
  42. }
  43. }
  44. //监控服务变化
  45. void ZkClient::ServiceWatcher(zhandle_t *zh, int type, int state, const char *path, void *watcherCtx) {
  46. cout << "type:" << type << endl;
  47. cout << "state:" << state << endl;
  48. cout << "path:" << path << endl;
  49. //  cout << "watcherCtx:" << (char*)watcherCtx << endl;
  50. cout << "ZOO_CHILD_EVENT:" << ZOO_CHILD_EVENT << endl;
  51. if (ZOO_CHILD_EVENT == type) {
  52. cout << "ServiceWatcher ZOO_CHILD_EVENT" << endl;
  53. ZkClient::Instance().Update();//更新服务列表
  54. }
  55. }

服务端会每隔一段时间重新注册自己;

客户端在第一次与zk建立连接获取服务列表时,注册监听函数。zk当节点发生变化时,通知客户端,客户端重新获取服务列表,并注册事件。

时间: 2024-11-04 00:32:36

zk系列-c++下zookeeper使用实例的相关文章

ZooKeeper系列之二:Zookeeper常用命令

ZooKeeper系列之二:Zookeeper常用命令 http://blog.csdn.net/xiaolang85/article/details/13021339 ZooKeeper服务命令: 在准备好相应的配置之后,可以直接通过zkServer.sh 这个脚本进行服务的相关操作 1. 启动ZK服务:       sh bin/zkServer.sh start 2. 查看ZK服务状态: sh bin/zkServer.sh status 3. 停止ZK服务:       sh bin/z

centos下zookeeper集群搭建

单机模式: 1)  首先下载zookeeper压缩包, 这里采用zookeeper3.4.8.... wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.8/zookeeper-3.4.8.tar.gz 2)   解压缩 首先创建文件夹,这里放到/user/zookeeper/文件夹下 mkdir zookeeper1 mkdir zookeeper2 mkdir zookeeper3 创建三个文件夹用于存放三个实例,下面解压

IDEA上创建 Maven SpringBoot + zookeeper +dubbo 实例

概述 首先声明,本文是学习总结类型的博客内容,如有雷同纯属学习.本位主要结合zookeeper和dubbo做个简单实例.目前来说,一般网站架构随着业务的发展,逻辑越来越复杂,数据量越来越大,交互越来越多之后的常规方案演进历程. 其次,当服务越来越多之后,我们需要做哪些服务治理? Dubbo主要处理服务,约束服务提供者和消费者之间的关系.Dubbo处理消费者.提供者以及注册的关系如下: Zookeeper使用 ZooKeeper 虽然是一个针对分布式系统的协调服务,但它本身也是一个分布式应用程序.

ZooKeeper系列之二:Zookeeper应用介绍与安装部署大神必学

前言最近有很多粉丝反映怎么学好java?Zookeepr是什么? java开发技术不是一两天就能学好的,Zookeepr也是一样的道理,关键还得看你怎么去学,跟谁去学,俗话说的好师傅领进门,修行靠个人,这个不是短时间类所能完成的任务,有想法的上方关注,下方留言"学习"我教你!1 Zookeeper概述#ZooKeeper是一个为分布式应用所设计的分布的.开源的协调服务,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,简化分布式应用协调及其管理的难度,提供高性能的分布式服务.Zo

【ZooKeeper系列】3.ZooKeeper源码环境搭建

前文阅读: [ZooKeeper系列]1.ZooKeeper单机版.伪集群和集群环境搭建 [ZooKeeper系列]2.用Java实现ZooKeeper API的调用 在系列的前两篇文章中,介绍了ZooKeeper环境的搭建(包括单机版.伪集群和集群),对创建.删除.修改节点等场景用命令行的方式进行了测试,让大家对ZooKeeper环境搭建及常用命令行有初步的认识,也为搭建ZooKeeper的开发环境.生产环境起到了抛砖引玉的作用.也介绍了用Java来实现API的调用,包括节点的增.删.改.查.

ECharts系列 - 柱状图(条形图)实例一

ECharts主页:  http://echarts.baidu.com/index.html ECharts-2.1.8下载地址:  http://echarts.baidu.com/build/echarts-2.1.8.zip ECharts官方实例:  http://echarts.baidu.com/doc/example.html ECharts官方API文档:  http://echarts.baidu.com/doc/doc.html ECharts系列 - 柱状图(条形图)实例

ZooKeeper系列4:ZooKeeper API简介及编程

问题导读: 1.ZooKeeper API 共包含几个包? 2.如何使用ZooKeeper API 创建zookeeper应用程序? 1)ZooKeeper API 简介 ZooKeeper API 共包含 5 个包,分别为: org.apache.zookeeper , org.apache.zookeeper.data ,org.apache.zookeeper.server , org.apache.zookeeper.server.quorum 和org.apache.zookeeper

ZooKeeper系列2:ZooKeeper的运行

问题导读1.如何启动ZooKeeper 服务?2.如何启动集群 1)单机模式 用户可以通过下面的命令来启动 ZooKeeper 服务: zkServer.sh start 复制代码 这个命令默认情况下执行 ZooKeeper 的 conf 文件夹下的 zoo.cfg 配置文件.当运行成功用户会看到类似如下的提示界面: [email protected]:~# zkServer.sh start JMX enabled by default Using config: /root/hadoop-0

centos7下Zookeeper+sheepdog集群搭建

zookeeper 安装命令 yum install zookeeper -y            (版本:zookeeper.x86_64      3.4.6-1) yum install zookeeper-lib -y   (版本:zookeeper-lib.x86_64   3.4.6-1) 配置文件:/etc/zookeeper/zoo.cfg 作如下修改: maxClientCnxns=50 tickTime=2000 initLimit=10 syncLimit=5 dataD