命令基本语法 | 功能描述 |
---|---|
help | 显示所有操作命令 |
ls path [watch] | 使用 ls 命令来查看当前znode中所包含的内容 |
ls2 path [watch] | 查看当前节点数据并能看到更新次数等数据 |
create | 普通创建-s 含有序列-e 临时(重启或者超时消失) |
get path [watch] | 获得节点的值 |
set | 设置节点的具体值 |
stat | 查看节点状态 |
delete | 删除节点 |
rmr | 递归删除节点 |
1.启动客户端
[hadoop103 zookeeper-3.4.10]$ bin/zkCli.sh
2.显示所有操作命令
[zk: localhost:2181(CONNECTED) 1] help
3.查看当前znode中所包含的内容
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
4.查看当前节点详细数据
[zk: localhost:2181(CONNECTED) 1] ls2 /
[zookeeper]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
5.分别创建2个普通节点
[zk: localhost:2181(CONNECTED) 3] create /sanguo "jinlian"
Created /sanguo
[zk: localhost:2181(CONNECTED) 4] create /sanguo/shuguo "liubei"
Created /sanguo/shuguo
6.获得节点的值
[zk: localhost:2181(CONNECTED) 5] get /sanguo
jinlian
cZxid = 0x100000003
ctime = Wed Aug 29 00:03:23 CST 2018
mZxid = 0x100000003
mtime = Wed Aug 29 00:03:23 CST 2018
pZxid = 0x100000004
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 1
[zk: localhost:2181(CONNECTED) 6]
[zk: localhost:2181(CONNECTED) 6] get /sanguo/shuguo
liubei
cZxid = 0x100000004
ctime = Wed Aug 29 00:04:35 CST 2018
mZxid = 0x100000004
mtime = Wed Aug 29 00:04:35 CST 2018
pZxid = 0x100000004
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
7.创建短暂节点
[zk: localhost:2181(CONNECTED) 7] create -e /sanguo/wuguo "zhouyu"
Created /sanguo/wuguo
(1)在当前客户端是能查看到的
[zk: localhost:2181(CONNECTED) 3] ls /sanguo
[wuguo, shuguo]
(2)退出当前客户端然后再重启客户端
[zk: localhost:2181(CONNECTED) 12] quit
[hadoop104 zookeeper-3.4.10]$ bin/zkCli.sh
(3)再次查看根目录下短暂节点已经删除
[zk: localhost:2181(CONNECTED) 0] ls /sanguo
[shuguo]
8.创建带序号的节点
(1)先创建一个普通的根节点/sanguo/weiguo
[zk: localhost:2181(CONNECTED) 1] create /sanguo/weiguo "caocao"
Created /sanguo/weiguo
(2)创建带序号的节点
[zk: localhost:2181(CONNECTED) 2] create -s /sanguo/weiguo/xiaoqiao "jinlian"
Created /sanguo/weiguo/xiaoqiao0000000000
[zk: localhost:2181(CONNECTED) 3] create -s /sanguo/weiguo/daqiao "jinlian"
Created /sanguo/weiguo/daqiao0000000001
[zk: localhost:2181(CONNECTED) 4] create -s /sanguo/weiguo/diaocan "jinlian"
Created /sanguo/weiguo/diaocan0000000002
如果原来没有序号节点,序号从0开始依次递增。如果原节点下已有2个节点,则再排序时从2开始,以此类推。
9.修改节点数据值
[zk: localhost:2181(CONNECTED) 6] set /sanguo/weiguo "simayi"
10.节点的值变化监听
(1)在hadoop104主机上注册监听/sanguo节点数据变化
[zk: localhost:2181(CONNECTED) 26] [zk: localhost:2181(CONNECTED) 8] get /sanguo watch
(2)在hadoop103主机上修改/sanguo节点的数据
[zk: localhost:2181(CONNECTED) 1] set /sanguo "xisi"
(3)观察hadoop104主机收到数据变化的监听
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/sanguo
11.节点的子节点变化监听(路径变化)
(1)在hadoop104主机上注册监听/sanguo节点的子节点变化
[zk: localhost:2181(CONNECTED) 1] ls /sanguo watch
[aa0000000001, server101]
(2)在hadoop103主机/sanguo节点上创建子节点
[zk: localhost:2181(CONNECTED) 2] create /sanguo/jin "simayi"
Created /sanguo/jin
(3)观察hadoop104主机收到子节点变化的监听
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/sanguo
12.删除节点
[zk: localhost:2181(CONNECTED) 4] delete /sanguo/jin
13.递归删除节点
[zk: localhost:2181(CONNECTED) 15] rmr /sanguo/shuguo
14.查看节点状态
[zk: localhost:2181(CONNECTED) 17] stat /sanguo
cZxid = 0x100000003
ctime = Wed Aug 29 00:03:23 CST 2018
mZxid = 0x100000011
mtime = Wed Aug 29 00:21:23 CST 2018
pZxid = 0x100000014
cversion = 9
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 1
1.创建一个Maven工程
2.添加pom文件
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>RELEASEversion>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-coreartifactId>
<version>2.8.2version>
dependency>
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
<version>3.4.10version>
dependency>
dependencies>
3.拷贝log4j.properties文件到项目根目录
需要在项目的src/main/resources目录下,新建一个文件,命名为“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
//注意:在connectString中,不能有空格,否则会报java.net.UnknownHostException异常
private static final String CONNECT_STRING = "CentOS001:2181,CentOS004:2181,CentOS005:2181";
private int SESSION_TIMEOUT = 2000;
private ZooKeeper zkClient;
@Before
public void init() throws IOException {
zkClient = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println("---------start----------");
// 收到事件通知后的回调函数(用户的业务逻辑)
System.out.println("====================:"+event.getType() + "--" + event.getPath());
List<String> children;
// 再次启动监听
try {
children = zkClient.getChildren("/", true);
for (String child : children) {
System.out.println(child);
}
System.out.println("---------end----------");
} catch (KeeperException |InterruptedException e) {
e.printStackTrace();
}
}
});
}
/**
* 1 创建节点
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void createNode() throws KeeperException, InterruptedException {
String path = zkClient.create("/htzw", "hangtian".getBytes(), Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
System.out.println(path);
}
/**
* 2 获取子节点 并监控节点的变化
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void getDataAndWatch() throws KeeperException, InterruptedException {
List<String> children = zkClient.getChildren("/", true);
for (String child : children) {
System.out.println(child);
}
// 延时阻塞
Thread.sleep(Long.MAX_VALUE);
}
/**
* 3 判断节点是否存在
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void exist() throws KeeperException, InterruptedException {
Stat stat = zkClient.exists("/htzw", false);
System.out.println(stat == null ? "not exist" : "exist");
}
1.需求
某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线。
2.需求分析,如图5-12所示
服务器动态上下线案例分析
3.具体实现
(0)先在集群上创建/servers节点
[zk: localhost:2181(CONNECTED) 10] create /servers "servers"
Created /servers
(1)服务器端向Zookeeper注册代码
public class DistributeServer {
private static final String CONNECT_STRING = "CentOS001:2181,CentOS004:2181,CentOS005:2181";
private static final int SESSION_TIMEOUT = 2000;
private ZooKeeper zkClient;
/**
* 创建到zk的客户端连接
* @throws IOException
*/
private void getConnect() throws IOException {
zkClient = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, event -> {
});
}
private void business() throws InterruptedException {
System.out.println("working ...");
Thread.sleep(Long.MAX_VALUE);
}
/**
* 注册服务器
* @param hostname
* @throws KeeperException
* @throws InterruptedException
*/
private void registerServer(String hostname) throws KeeperException, InterruptedException {
String path = zkClient.create("/servers/server", hostname.getBytes(),
Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(hostname + "is online ---psth:"+path);
}
public static void main(String[] args) throws Exception {
DistributeServer server = new DistributeServer();
// 1 连接zookeeper集群
server.getConnect();
// 2 注册节点
server.registerServer("10.0.1.55");
// 3 业务逻辑处理
server.business();
}
}
(2)客户端代码
public class DistributeClient {
private String CONNECT_STRING = "CentOS001:2181,CentOS004:2181,CentOS005:2181";
private int SESSION_TIMEOUT = 2000;
private ZooKeeper zkClient;
/**
* 业务功能
* @throws InterruptedException
*/
private void business() throws InterruptedException {
System.out.println("client is working ...");
Thread.sleep(Long.MAX_VALUE);
}
/**
* 获取服务器列表信息
* @throws KeeperException
* @throws InterruptedException
*/
private void getServerList() throws KeeperException, InterruptedException {
//获取服务器子节点信息,并且对父节点进行监听
List<String> children = zkClient.getChildren("/servers", true);
// 存储服务器节点主机名称集合
ArrayList<String> hosts = new ArrayList<>();
// 遍历所有节点,获取节点中的主机名称信息
for (String child : children) {
byte[] data = zkClient.getData("/servers/" + child, false, null);
hosts.add(new String(data));
}
// 将所有在线主机名称打印到控制台
System.out.println("*****************************");
System.out.println(hosts);
System.out.println("*****************************");
}
/**
* 创建到zk的客户端连接
* @throws IOException
*/
private void getConnect() throws IOException {
zkClient = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, event -> {
// 再次启动监听
try {
getServerList();
} catch (Exception e) {
e.printStackTrace();
}
});
}
public static void main(String[] args) throws Exception {
DistributeClient client = new DistributeClient();
// 1 获取zookeeper集群连接
client.getConnect();
// 2 注册监听
client.getServerList();
// 3 业务逻辑处理
client.business();
}
}