Zookeeper 客户端
zookeeper 官方的客户端没有和服务端代码分离,他们为同一个jar 文件,所以我们直接引入zookeeper的maven即可, 这里版本请保持与服务端版本一致,不然会有很多兼容性的问题
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.8</version>
</dependency>
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, ZKClientConfig)
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly, HostProvider)
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly, HostProvider, ZKClientConfig)
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly)
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly, ZKClientConfig)
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, long, byte[])
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, long, byte[], boolean, HostProvider)
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, long, byte[], boolean, HostProvider, ZKClientConfig)
ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, long, byte[], boolean)
- connectString: ZooKeeper服务器列表,由英文逗号分开的host:port字符串组成,每一个都代表一台ZooKeeper机器,如, host1:port1,host2:port2,host3:port3。另外,也可以在connectString中设置客户端连接上ZooKeeper后的根目录,方法是在host:port字符串之后添加上这个根目录,例如,host1:port1,host2:port2,host3:port3/zk-base,这样就指定了该客户端连接上ZooKeeper服务器之后,所有对ZooKeeper的操作,都会基于这个根目录。例如,客户端对/sub-node 的操作,最终创建 /zk-node/sub-node, 这个目录也叫Chroot,即客户端隔离命名空间。
- sessionTimeout: 会话的超时时间,是一个以“毫秒”为单位的整型值。在ZooKeeper中有会话的概念,在一个会话周期内,ZooKeeper客户端和服务器之间会通过心跳检测机制来维持会话的有效性,一旦在sessionTimeout时间内没有进行有效的心跳检测,会话就会失效。
- watcher: ZooKeeper允许客户端在构造方法中传入一个接口 watcher (org.apache. zookeeper.Watcher)的实现类对象来作为默认的Watcher事件通知处理器。当然,该参数可以设置为null 以表明不需要设置默认的 Watcher处理器。
- canBeReadOnly: 这是一个boolean类型的参数,用于标识当前会话是否支持“read-only(只读)”模式。默认情况下,在ZooKeeper集群中,一个机器如果和集群中过半及以上机器失去了网络连接,那么这个机器将不再处理客户端请求(包括读写请求)。但是在某些使用场景下,当ZooKeeper服务器发生此类故障的时候,我们还是希望ZooKeeper服务器能够提供读服务(当然写服务肯定无法提供)——这就是 ZooKeeper的“read-only”模式。
- sessionId和 sessionPasswd: 分别代表会话ID和会话秘钥。这两个参数能够唯一确定一个会话,同时客户端使用这两个参数可以实现客户端会话复用,从而达到恢复会话的效果。具体使用方法是,第一次连接上ZooKeeper服务器时,通过调用ZooKeeper对象实例的以下两个接口,即可获得当前会话的ID和秘钥:long getSessionId();byte[] getSessionPasswd( );荻取到这两个参数值之后,就可以在下次创建ZooKeeper对象实例的时候传入构造方法了
代码演示
@Slf4j
public class Zookeeper {
private static final String ADDRESS = "116.62.162.47:2181";
private static final int SESSION_TIMEOUT = 60 * 1000;
private static ZooKeeper zooKeeper;
private static final String NODE = "/node";
@Before
public void before() {
try {
CountDownLatch countDownLatch = new CountDownLatch(1);
zooKeeper = new ZooKeeper(ADDRESS, SESSION_TIMEOUT, event -> {
if (event.getState() == Watcher.Event.KeeperState.SyncConnected && event.getType() == Watcher.Event.EventType.None) {
countDownLatch.countDown();
log.info("连接成功!");
}
});
log.info("连接中...");
countDownLatch.await();
} catch (Throwable cause) {
cause.printStackTrace();
}
}
@Test
public void createTest() {
try {
String path = zooKeeper.create(NODE, "data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
log.info(path);
} catch (Throwable cause) {
cause.printStackTrace();
}
}
@Test
public void createAsyncTest() {
try {
zooKeeper.create(NODE, "data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT,
(rc, path, ctx, name) -> log.info("rc {}, path {}, ctx {}, name {}", rc, path, ctx, name), "context");
TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
} catch (Throwable cause) {
cause.printStackTrace();
}
}
@Test
public void setTest() {
try {
Stat stat = new Stat();
byte[] data = zooKeeper.getData(NODE, false, stat);
log.info("修改前: {}", new String(data));
zooKeeper.setData(NODE, "new data".getBytes(), stat.getVersion());
byte[] dataAfter = zooKeeper.getData(NODE, false, stat);
log.info("修改后: {}", new String(dataAfter));
} catch (Throwable cause) {
cause.printStackTrace();
}
}
@Test
public void getTest() {
try {
Watcher watcher = new Watcher() {
@SneakyThrows
@Override
public void process(WatchedEvent event) {
if (event.getType() == Event.EventType.NodeDataChanged && null != event.getPath() && event.getPath().equals(NODE)) {
byte[] data = zooKeeper.getData(NODE, this, null);
log.info(new String(data));
}
}
};
Stat stat = new Stat();
byte[] data = zooKeeper.getData(NODE, watcher, stat);
log.info(new String(data));
TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
} catch (Throwable cause) {
cause.printStackTrace();
}
}
}
集群模式下的使用
bin/zkCli.sh -server ip1:port1,ip2:port2,ip3:port3
../bin/zkCli.sh -server 172.16.138.202:2281,172.16.138.202:2282,172.16.138.202:2283,172.16.138.202:2284
private static final String ADDRESS = "116.62.162.48:2281,116.62.162.48:2282,116.62.162.48:2283,116.62.162.48:2284";
使用单独的ip和端口也可以连接, 但是多ip和端口的方式在服务宕机的时候能自动切换到服务正常的机器上
本文介绍了Zookeeper客户端的使用。官方客户端与服务端代码在同一jar文件,引入maven时版本需与服务端一致。还阐述了连接参数,如connectString、sessionTimeout等的含义。代码演示部分提及集群模式下多ip和端口连接可在服务宕机时自动切换。

528

被折叠的 条评论
为什么被折叠?



