ZooKeeper 支持 Java
和 C
的API接口。本文将介绍使用 C/C++
语言客户端库的编译安装和使用入门。
一、编译安装
PS:就在上一篇文章还觉得安装和配置
jdk
、maven
麻烦,所以当时选择apache-zookeeper-[version]-bin.tar.gz
的版本。然而,本文编译Zookeeper
的C/C++
API 动态库,还是避免不了安装jdk
、maven
。
出来混,总是要还的 (๑•̌.•๑)
1.安装依赖
安装jdk(建议11及以上,实测使用 jdk1.8 编译Zookeeper时会报错!!)
# 依赖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
版本安装为例)
# 下载 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"
安装其他依赖
# 安装 cppunit
[root@Ali ~]# yum install cppunit -y
[root@Ali ~]# yum install cppunit-devel -y
2.编译API动态库
# 下载源码
[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++接口操作数据
#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;
}
运行示例
[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_create
、zoo_get
等接口找不到。
原因:zoo_create
、zoo_get
等同步接口。在 zookeeper.h
的头文件中,使用 #ifdef THREADED
控制屏蔽了zoo_create
、zoo_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
节