启动Zookeeper集群:bin/zkServer.sh start
查看当前服务器为集群中的哪个角色:bin/zkServer.sh status
一、客户端操作
1.启动客户端:bin/zkCli.sh
2.显示所有操作命令 help
3.查看当前 znode 中所包含的内容 ls /
4.查看当前节点详细数据:ls2 /
5.创建普通节点:create /sanguo "jinlian"
create /sanguo/shuguo liubei
6.获取节点的值:get /sanguo
7.创建短暂节点:create -e /sanguo/wuguo "zhaoyu"
(1)在当前会话可见 ls /sanguo/wuguo 有结果
(2)退出客户端,再次启动客户端, ls /sanguo/wuguo 发现没结果,节点已被删除。
8.创建带序号的节点:create /sanguo/weiguo "caocao"
create /sanguo/weiguo "caocao"
create /sanguo/weiguo "caocao"
如果原来没有序号节点,序号从 0 开始依次递增。如果原节点下已有 2 个节点,则再排序时从 2 开始,以此类推
9.修改节点的值 : set /sanguo/weiguo "simayi"
10节点的值变化监听:在第一台主机上通过客户端注册对/sanguo节点的数据变化监听:get /sanguo watch
在第二台主机上修改/sanguo节点的数据
在第一台主机收到数据变化的监听
WatchedEvent state:SyncConnected type:NodeDataChanged path:/sanguo
11.节点的子节点变化监听(路径变化)
在第一台主机上通过客户端注册对/sanguo节点的路径变化监听:ls /sanguo watch
在第二台主机上增加/sanguo下的一个子节点:create /sanguo/xixi “haha”
在第一台主机收到数据变化的监听
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/sanguo
12.删除节点 delete /sanguo/xixi
13.递归删除节点:rmr /sanguo/shuguo
14.查看节点的状态 stat /sanguo
二、Java原生API调用
1.创建一个Maven工程
2.添加pom文件
<?xml version="1.0" encoding="utf-8"?>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zook eeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
</dependencies>
3.log4j.properties
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
4.创建Zookeeper客户端
private static String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zkClient = null;
@Before
public void init() throws Exception {
zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
// 收到事件通知后的回调函数(用户的业务逻辑)
System.out.println(event.getType() + "--" + event.getPath());
}
});
}
5.创建一个节点
// 创建子节点
@Test
public void create() throws Exception {
// 数据的增删改查
// 参数1:要创建的节点的路径; 参数2:节点数据 ; 参数3:节点权限 ;参数4:节点的类型
String nodeCreated = zkClient.create("/eclipse", "hello zk".getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
}
6.获取子节点
// 获取子节点
@Test
public void getChildren() throws Exception {
List children = zkClient.getChildren("/", true);
for (String child : children) {
System.out.println(child);
}
// 延时阻塞
Thread.sleep(Long.MAX_VALUE);
}
7.判断Znode是否存在
// 判断ZNode是否存在
@Test
public void exist() throws Exception {
Stat stat = zkClient.exists("/eclipse", false);
System.out.println(stat == null ? "not exist" : "exist");
}
三、监听服务器节点动态上下线案例、
1.在集群上先创建一个server节点
create /servers "servers"
2.客户端做监听,服务端去注册一个临时节点
客户端代码
package com.atguigu.zkcase;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
public class DistributeClient {
private static String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zk = null;
private String parentNode = "/servers";
// 创建到zk的客户端连接
public void getConnect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
// 再次启动监听
try {
getServerList();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
// 获取服务器列表信息
public void getServerList() throws Exception {
// 1获取服务器子节点信息,并且对父节点进行监听
List children = zk.getChildren(parentNode, true);
// 2存储服务器信息列表
ArrayList servers = new ArrayList();
// 3遍历所有节点,获取节点中的主机名称信息
for (String child : children) {
byte[] data = zk.getData(parentNode + "/" + child, false, null);
servers.add(new String(data));
}
// 4打印服务器列表信息
System.out.println(servers);
}
// 业务功能
public void business() throws Exception {
System.out.println("client is working ...");
Thread.sleep(Long.MAX_VALUE);
}
public static void main(String[] args) throws Exception {
// 1获取zk连接
DistributeClient client = new DistributeClient();
client.getConnect();
// 2获取servers的子节点信息,从中获取服务器信息列表
client.getServerList();
// 3业务进程启动
client.business();
}
}
服务端代码
package com.atguigu.zkcase;
import java.io.IOException;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;
public class DistributeServer {
private static String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zk = null;
private String parentNode = "/servers";
// 创建到zk的客户端连接
public void getConnect() throws IOException{
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
}
});
}
// 注册服务器
public void registServer(String hostname) throws Exception{
String create = zk.create(parentNode + "/server", hostname.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(hostname +" is online "+ create);
}
// 业务功能
public void business(String hostname) throws Exception{
System.out.println(hostname+" is working ...");
Thread.sleep(Long.MAX_VALUE);
}
public static void main(String[] args) throws Exception {
// 1 获取zk连接
DistributeServer server = new DistributeServer();
server.getConnect();
// 2 利用zk连接注册服务器信息
server.registServer(args[0]);
// 3 启动业务功能
server.business(args[0]);
}
}