使用C/C++ API接口操作 Zookeeper 数据

ZooKeeper 支持 JavaC 的API接口。本文将介绍使用 C/C++ 语言客户端库的编译安装和使用入门。

一、编译安装

PS:就在上一篇文章还觉得安装和配置 jdkmaven 麻烦,所以当时选择 apache-zookeeper-[version]-bin.tar.gz 的版本。然而,本文编译 ZookeeperC/C++ API 动态库,还是避免不了安装 jdkmaven

出来混,总是要还的 (๑•̌.•๑)

1.安装依赖

安装jdk(建议11及以上,实测使用 jdk1.8 编译Zookeeper时会报错!!)

bash 复制代码
# 依赖Java11
[root@Ali ~]# yum install -y java-11-openjdk.x86_64 
[root@Ali ~]# yum install -y java-11-openjdk-devel.x86_64 
[root@Ali ~]# yum install -y java-11-openjdk-headless.x86_64
# 查看java安装
[root@Ali ~]# rpm -qa | grep jdk 
	java-11-openjdk-devel-11.0.23.0.9-2.el7_9.x86_64
	copy-jdk-configs-3.3-11.el7_9.noarch
	java-11-openjdk-11.0.23.0.9-2.el7_9.x86_64
	java-11-openjdk-headless-11.0.23.0.9-2.el7_9.x86_64

安装maven

maven 官方下载地址 下载需要的 maven 版本(本文以 apache-maven-3.9.6 版本安装为例)

bash 复制代码
# 下载 apache-maven-3.9.6-bin.tar.gz
[root@Ali ~]# wget https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz
[root@Ali ~]# tar xzvf apache-maven-3.9.6-bin.tar.gz
[root@Ali ~]# mv apache-maven-3.9.6 /usr/local/maven

# 设置 PATH 环境变量: 将 /usr/local/maven/bin/ 添加到PATH
[root@Ali ~]# vim /etc/bash
PATH=/usr/local/maven/bin/:$PATH
export PATH

# 查看版本
[root@Ali ~]# mvn -v
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /usr/local/maven
Java version: 11.0.23, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-11-openjdk-11.0.23.0.9-2.el7_9.x86_64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-1160.105.1.el7.x86_64", arch: "amd64", family: "unix"

安装其他依赖

bash 复制代码
# 安装 cppunit
[root@Ali ~]# yum install cppunit -y
[root@Ali ~]# yum install cppunit-devel -y

2.编译API动态库

bash 复制代码
# 下载源码
[root@Ali ~]# wget https://dlcdn.apache.org/zookeeper/zookeeper-3.9.2/apache-zookeeper-3.9.2.tar.gz
[root@Ali ~]# tar xzvf apache-zookeeper-3.9.2.tar.gz

# 在zookeeper-jute 执行 mvn compile
[root@Ali ~]# cd apache-zookeeper-3.9.2/zookeeper-jute
[root@Ali zookeeper-jute]# mvn compile
# ... ...
[INFO] Compiling 108 source files to /root/apache-zookeeper-3.9.2/zookeeper-jute/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  09:36 min
[INFO] Finished at: 2024-05-22T16:45:37+08:00
[INFO] ------------------------------------------------------------------------

# 切换到 zookeeper-client/zookeeper-client-c, 执行 autoreconf -if
[root@Ali zookeeper-jute]# cd ../zookeeper-client/zookeeper-client-c
[root@Ali zookeeper-client-c]# autoreconf -if

# 编译安装
[root@Ali zookeeper-client-c]# ./configure

其中 ./configure <your-options>  可选项:
    --enable-debug Enables optimization and enables debug info compiler options. (Disabled by default.)
    --without-syncapi Disables Sync API support; zookeeper_mt library won't be built. (Enabled by default.)
    --disable-static Do not build static libraries. (Enabled by default.)
    --disable-shared Do not build shared libraries. (Enabled by default.)

[root@Ali zookeeper-client-c]# make
[root@Ali zookeeper-client-c]# make check
[root@Ali zookeeper-client-c]# make install

二、使用C++接口操作数据

cpp 复制代码
#include <string.h>
#include <zookeeper/zookeeper.h>

void watcher(zhandle_t *zh, int type, int state, const char *path, void *context) {
    // watcher function body
}

int main() {
    // create zookeeper handle
    zhandle_t *zkhandle = zookeeper_init("localhost:12181", watcher, 20000, 0, 0, 0);
    if (zkhandle == nullptr) {
        return -1;
    }

    // create node
    int retval = 0;
    char buffer[128];
    int buffer_length = sizeof(buffer);
    (void)memset(buffer, 0, sizeof(buffer));
    struct ACL ACL_ANYONE[] = {{ZOO_PERM_ALL, ZOO_ANYONE_ID_UNSAFE}};
    struct ACL_vector ACL_ANYONE_VEC = {1, ACL_ANYONE};
    retval = zoo_create(zkhandle, "/my_node","value", 5, &ACL_ANYONE_VEC,
                            ZOO_EPHEMERAL, buffer, sizeof(buffer)-1);
    if(retval == ZOK){
        printf("zoo_create data for /my_node is %s\n", buffer);
    }
    else{
        printf("zoo_create failed: code=%d\n", retval);
    }

    // get node data
    (void)memset(buffer, 0, sizeof(buffer));
    retval = zoo_get(zkhandle, "/my_node", 0, buffer, &buffer_length, nullptr);
    if (retval == ZOK) {
        printf("zoo_get data for /my_node is %s\n", buffer);
    }
    else{
        printf("zoo_get failed: code=%d\n", retval);
    }

    // close Zookeeper handle
    zookeeper_close(zkhandle);

    return 0;
}

运行示例

bash 复制代码
[wengjianhong@Ali testzone]$ g++ test_zookeeper.cpp --std=c++11 -lzookeeper_mt -DTHREADED -o test_zookeeper

[wengjianhong@Ali testzone]$ ./test_zookeeper
2024-05-22 19:25:35,325:12819(0x7fc5fdca3880):ZOO_INFO@log_env@1250: Client environment:zookeeper.version=zookeeper C client 3.9.2
2024-05-22 19:25:35,325:12819(0x7fc5fdca3880):ZOO_INFO@log_env@1254: Client environment:host.name=Ali
2024-05-22 19:25:35,325:12819(0x7fc5fdca3880):ZOO_INFO@log_env@1261: Client environment:os.name=Linux
2024-05-22 19:25:35,325:12819(0x7fc5fdca3880):ZOO_INFO@log_env@1262: Client environment:os.arch=3.10.0-1160.105.1.el7.x86_64
2024-05-22 19:25:35,325:12819(0x7fc5fdca3880):ZOO_INFO@log_env@1263: Client environment:os.version=#1 SMP Thu Dec 7 15:39:45 UTC 2023
2024-05-22 19:25:35,325:12819(0x7fc5fdca3880):ZOO_INFO@log_env@1271: Client environment:user.name=wengjianhong
2024-05-22 19:25:35,325:12819(0x7fc5fdca3880):ZOO_INFO@log_env@1279: Client environment:user.home=/home/wengjianhong
2024-05-22 19:25:35,325:12819(0x7fc5fdca3880):ZOO_INFO@log_env@1291: Client environment:user.dir=/home/wengjianhong/testzone
2024-05-22 19:25:35,325:12819(0x7fc5fdca3880):ZOO_INFO@zookeeper_init_internal@1344: Initiating client connection, host=localhost:12181 sessionTimeout=20000 watcher=0x40087d sessionId=0 sessionPasswd=<null> context=(nil) flags=0
2024-05-22 19:25:35,326:12819(0x7fc5fa73a700):ZOO_INFO@check_events@2987: initiated connection to server 127.0.0.1:12181
2024-05-22 19:25:35,329:12819(0x7fc5fa73a700):ZOO_INFO@finalize_session_establishment@2865: session establishment complete on server 127.0.0.1:12181, sessionId=0x100024f5eba000c, negotiated timeout=20000
zoo_create data for /my_node is /my_node
zoo_get data for /my_node is value
2024-05-22 19:25:35,333:12819(0x7fc5fdca3880):ZOO_INFO@zookeeper_close@3850: Closing zookeeper sessionId=0x100024f5eba000c to 127.0.0.1:12181
2024-05-22 19:25:35,335:12819(0x7fc5fdca3880):ZOO_INFO@zookeeper_close@3872: Freeing zookeeper resources for sessionId=0x100024f5eba000c

重要说明

编译 C++ 代码的时候这里必须指定链接 lzookeeper_mt 的动态库 和 添加 -DTHREADED 编译选项。否则会导致 zoo_createzoo_get 等接口找不到。

原因:zoo_createzoo_get 等同步接口。在 zookeeper.h 的头文件中,使用 #ifdef THREADED 控制屏蔽了zoo_createzoo_get 等接口,必须使用-DTHREADED 编译选项才能使用。原文如下:

If you are building a multithreaded client, compile with -DTHREADED compiler flag to enable the multi-threaded version of the library, and then link against the zookeeper_mt library.
If you are building a single-threaded client, do not compile with -DTHREADED, and be sure to link against the_zookeeper_st_library.

更多接口使用,请参考 apache-zookeeper-3.9.2/zookeeper-client/zookeeper-client-c/include/ 目录下的 zookeeper.h 等头文件

本文参考自 Zookeeper程序开发指南C Binding

相关推荐
一律清风1 小时前
QT-文件创建时间修改器
c++·qt
风清扬_jd1 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
Death2002 小时前
Qt 6 相比 Qt 5 的主要提升与更新
开发语言·c++·qt·交互·数据可视化
麻辣韭菜4 小时前
网络基础 【HTTP】
网络·c++·http
阿史大杯茶4 小时前
Codeforces Round 976 (Div. 2 ABCDE题)视频讲解
数据结构·c++·算法
转调5 小时前
每日一练:地下城游戏
开发语言·c++·算法·leetcode
不穿格子衬衫5 小时前
常用排序算法(下)
c语言·开发语言·数据结构·算法·排序算法·八大排序
wdxylb5 小时前
使用C++的OpenSSL 库实现 AES 加密和解密文件
开发语言·c++·算法
aqua35357423585 小时前
蓝桥杯-财务管理
java·c语言·数据结构·算法
CSP126366 小时前
特别节目————集训总结
c++