转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/81349965
本文出自【我是干勾鱼的博客】
Ingredients:
-
Java:Java SE Development Kit 8u162(Oracle Java Archive),Linux下安装JDK修改环境变量
-
Zookeeper:zookeeper-3.4.12.tar.gz(Zookeeper Download Mirror,ZooKeeper Releases Archive)
1 Zookeeper简介
到官网了解Zookeeper Overview是最明确的啦!这里简单介绍一下。
1.1 Zookeeper是什么
Zookeeper官网中对Zookeeper的定义还是比较明确的:
ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. All of these kinds of services are used in some form or another by distributed applications. Each time they are implemented there is a lot of work that goes into fixing the bugs and race conditions that are inevitable. Because of the difficulty of implementing these kinds of services, applications initially usually skimp on them ,which make them brittle in the presence of change and difficult to manage. Even when done correctly, different implementations of these services lead to management complexity when the applications are deployed.
简单的说,Zookeeper作为一个协调管理者被用在分布式系统中。管理什么呢?分布式系统是由多个系统组成的,系统之间涉及的配置信息管理,命名规范,系统之间的信息同步,以及组服务等,这些工作肯定放在统一的管理平台上来管理会更加顺畅一些。Zookeeper就是负责这些工作的一个管理平台。
1.2 文件系统
Zookeeper提供了一个命名空间,很类似于一个文件系统。
ZooKeeper’s Hierarchical Namespace
与标准文件系统不太一样的是,Zookeeper里面的文件,既是文件也是文件夹,每个文件可以有子文件(也可以说是子文件夹),这样的每个文件被叫做一个“znode”。
由于Zookeeper是用来保管“协同数据”(coordination data)的,比如状态信息(status information),配置信息(configuration),位置信息(location information),所以每个znode文件都很小,一般也就是在“kilobyte range”级别的。
1.3 状态变化与监听通知机制
Zookeeper还支持监听(watches)机制。client可以在znodes上注册一个监听。当znode发生变化时这个监听会被触发,并将变化信息反馈给client。如果client与Zookeeper服务器之间的连接断开了,client本地也会收到相应的通知。
2 下载
下载zookeeper-3.4.12.tar.gz,在目录“/opt”创建文件夹“zookeeper”,将下载的文件放入其中并解压缩,最后文件的路径为:
/opt/zookeeper/zookeeper-3.4.12
再创建一个文件夹:
/opt/zookeeper/zookeeper-3.4.12_dataDir
3 单机模式安装
3.1 配置
复制文件:
conf/zoo_sample.cfg
并重命名为:
conf/zoo.cfg
配置该文件,在里面添加内容:
tickTime=2000
dataDir=dataDir=/opt/zookeeper/zookeeper-3.4.12_dataDir
clientPort=2181
3.2 启动
运行:
./bin/zkServer.sh start
结果:
./bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/zookeeper-3.4.12/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
3.3 查看状态
运行:
./bin/zkServer.sh status
结果:
./bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/zookeeper-3.4.12/bin/../conf/zoo.cfg
Mode: standalone
根据状态能看出是单机运行。
3.4 测试连接
运行:
./bin/zkCli.sh
结果:
./bin/zkCli.sh
Connecting to localhost:2181
2018-08-02 14:23:10,984 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.12-e5259e437540f349646870ea94dc2658c4e44b3b, built on 03/27/2018 03:55 GMT
2018-08-02 14:23:10,988 [myid:] - INFO [main:Environment@100] - Client environment:host.name=<NA>
2018-08-02 14:23:10,988 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.8.0_162
2018-08-02 14:23:10,990 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Oracle Corporation
2018-08-02 14:23:10,990 [myid:] - INFO [main:Environment@100] - Client environment:java.home=/opt/java/jdk1.8.0_162/jre
2018-08-02 14:23:10,990 [myid:] - INFO [main:Environment@100] - Client environment:java.class.path=/opt/zookeeper/zookeeper-3.4.12/bin/../build/classes:/opt/zookeeper/zookeeper-3.4.12/bin/../build/lib/*.jar:/opt/zookeeper/zookeeper-3.4.12/bin/../lib/slf4j-log4j12-1.7.25.jar:/opt/zookeeper/zookeeper-3.4.12/bin/../lib/slf4j-api-1.7.25.jar:/opt/zookeeper/zookeeper-3.4.12/bin/../lib/netty-3.10.6.Final.jar:/opt/zookeeper/zookeeper-3.4.12/bin/../lib/log4j-1.2.17.jar:/opt/zookeeper/zookeeper-3.4.12/bin/../lib/jline-0.9.94.jar:/opt/zookeeper/zookeeper-3.4.12/bin/../lib/audience-annotations-0.5.0.jar:/opt/zookeeper/zookeeper-3.4.12/bin/../zookeeper-3.4.12.jar:/opt/zookeeper/zookeeper-3.4.12/bin/../src/java/lib/*.jar:/opt/zookeeper/zookeeper-3.4.12/bin/../conf:.:/opt/java/jdk1.8.0_162/bin/dt.jar:/opt/java/jdk1.8.0_162/lib/tools.jar
2018-08-02 14:23:10,990 [myid:] - INFO [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2018-08-02 14:23:10,990 [myid:] - INFO [main:Environment@100] - Client environment:java.io.tmpdir=/tmp
2018-08-02 14:23:10,990 [myid:] - INFO [main:Environment@100] - Client environment:java.compiler=<NA>
2018-08-02 14:23:10,991 [myid:] - INFO [main:Environment@100] - Client environment:os.name=Linux
2018-08-02 14:23:10,991 [myid:] - INFO [main:Environment@100] - Client environment:os.arch=amd64
2018-08-02 14:23:10,991 [myid:] - INFO [main:Environment@100] - Client environment:os.version=4.4.0-93-generic
2018-08-02 14:23:10,991 [myid:] - INFO [main:Environment@100] - Client environment:user.name=root
2018-08-02 14:23:10,991 [myid:] - INFO [main:Environment@100] - Client environment:user.home=/root
2018-08-02 14:23:10,991 [myid:] - INFO [main:Environment@100] - Client environment:user.dir=/opt/zookeeper/zookeeper-3.4.12
2018-08-02 14:23:10,993 [myid:] - INFO [main:ZooKeeper@441] - Initiating client connection, connectString=localhost:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@277050dc
Welcome to ZooKeeper!
2018-08-02 14:23:11,016 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1028] - Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
JLine support is enabled
2018-08-02 14:23:11,134 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@878] - Socket connection established to localhost/127.0.0.1:2181, initiating session
2018-08-02 14:23:11,146 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1302] - Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x10008fcefa30001, negotiated timeout = 30000
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2181(CONNECTED) 0]
说明连接成功,并且介入到了Zookeeper的文件系统中。
3.5 常用命令
3.5.1 使用 ls 命令来查看当前 ZooKeeper 中所包含的内容
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
3.5.2 创建一个新的 znode ,使用 create /zkPro myData
[zk: localhost:2181(CONNECTED) 1] create /zkPro myData
Created /zkPro
3.5.3 再次使用 ls 命令来查看现在 zookeeper 中所包含的内容:
[zk: localhost:2181(CONNECTED) 2] ls /
[zookeeper, zkPro]
3.5.4 下面我们运行 get 命令来确认第二步中所创建的 znode 是否包含我们所创建的字符串:
[zk: localhost:2181(CONNECTED) 3] get /zkPro
myData
cZxid = 0xf
ctime = Thu Aug 02 14:32:01 CST 2018
mZxid = 0xf
mtime = Thu Aug 02 14:32:01 CST 2018
pZxid = 0xf
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
3.5.5 下面我们通过 set 命令来对 zk 所关联的字符串进行设置:
[zk: localhost:2181(CONNECTED) 4] set /zkPro myData2
cZxid = 0xf
ctime = Thu Aug 02 14:32:01 CST 2018
mZxid = 0x10
mtime = Thu Aug 02 14:38:40 CST 2018
pZxid = 0xf
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0
3.5.6 使用 get 命令再次查看:
[zk: localhost:2181(CONNECTED) 5] get /zkPro
myData2
cZxid = 0xf
ctime = Thu Aug 02 14:32:01 CST 2018
mZxid = 0x10
mtime = Thu Aug 02 14:38:40 CST 2018
pZxid = 0xf
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0
能够看到字符串“myData”被改为了“myData2”。
3.5.7 下面我们将刚才创建的 znode 删除
[zk: localhost:2181(CONNECTED) 6] delete /zkPro
3.5.8 再次使用 ls 命令查看
[zk: localhost:2181(CONNECTED) 7] ls /
[zookeeper]
能够看到名为“/zkPro”的znode被删除了。
3.6 使用Java API操作zookeeper
现在我们来做一个实验测试一下Zookeeper服务器的功能。
我们要做的是在zookeeper里增加一个znode目录节点,并且把配置信息存储在里面,接着写一段Java代码作为client来连接Zookeeper的server上,查看server目前的目录文件情况;然后再打开一个终端,连接到Zookeeper的server上,改变Zookeeper的目录文件情况,这时候Java代码作为client端会输出server端目录文件结构的改变 。
3.6.1 创建一个znode,并且保存一个配置信息
[zk: localhost:2181(CONNECTED) 7] create /username dongdong
[zookeeper]
然后查看“/username”的配置信息:
[zk: localhost:2181(CONNECTED) 7] ls /
[zookeeper]
3.6.2 使用Java制作一个client
3.6.2.1 Maven部分
client端创建一个maven项目:
<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.12</version>
<!-- <type>pom</type> -->
</dependency>
这里注意,在maven库中复制的结构里面有:
<type>pom</type>
部分,这里要将其注释掉,否则项目中不会加入:
zookeeper-3.4.12.jar
这个jar包,代码中的类也就无法继承:
org.apache.zookeeper.Watcher
这个监听器的接口。
3.6.2.2 Java代码部分
使用Java代码制作的client端如下:
package com.yhd.project.zookeepertest;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.ZooKeeper;
/**
* 分布式配置中心demo
*
* @author admin
*
*/
public class ZooKeeperProSync implements Watcher {
private static CountDownLatch connectedSemaphore = new CountDownLatch(1);
private static ZooKeeper zk = null;
private static Stat stat = new Stat();
public static void main(String[] args) throws Exception {
//Zookeeper配置数据存放路径
String path = "/username";
//连接Zookeeper并且注册一个默认的监听器,注明服务器的IP和端口
zk = new ZooKeeper("*.*.*.*:2181", 5000, new ZooKeeperProSync());
//等待zk连接成功的通知
connectedSemaphore.await();
//获取path目录节点的配置数据,并注册默认的监听器
System.out.println(new String(zk.getData(path, true, stat)));
Thread.sleep(Integer.MAX_VALUE);
}
public void process(WatchedEvent event) {
if (KeeperState.SyncConnected == event.getState()) { //zk连接成功通知事件
if ( EventType.None == event.getType() && null == event.getPath() ) {
connectedSemaphore.countDown();
} else if (event.getType() == EventType.NodeDataChanged) { //zk目录节点数据变化通知事件
try {
System.out.println("配置已修改,新值为:" +
new String(zk.getData(event.getPath(), true, stat)));
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
}
}
}
3.6.3 运行Java制作的client
运行java,结果如下:
log4j:WARN No appenders could be found for logger (org.apache.zookeeper.ZooKeeper).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
dongdong
因为之前在:
/username
这个znode下创建了:
dongdong
这个字符串,此处运行client,输出了这个字符串。
3.6.4 使用终端连接Zookeeper的server,改变znode的配置
- 1.连接server。
使用终端连接server,可以在Zookeeper的服务器上使用终端输入:
./bin/zkCli.sh
来连接server。
- 2.修改原有目录结构
先查看一下现有结构:
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper, username]
然后将原有的字符串“dongdong”修改为“dongdong123”。
[zk: localhost:2181(CONNECTED) 1] set /username dongdong123 //修改
cZxid = 0x14
ctime = Thu Aug 02 14:56:38 CST 2018
mZxid = 0x1c
mtime = Thu Aug 02 22:01:10 CST 2018
pZxid = 0x14
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 11
numChildren = 0
[zk: localhost:2181(CONNECTED) 2]
- 3.在client上查看变化。
现在是有2个client:Java代码制作的client,终端命令行的client。
在之前将“dongdong”修改为“dongdong123”的同时,Java代码的client端就会输出:
log4j:WARN No appenders could be found for logger (org.apache.zookeeper.ZooKeeper).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
dongdong
配置已修改,新值为:dongdong123
说明我们设置的监听器是生效了的。另外在终端命令行查看一下znode的信息:
[zk: localhost:2181(CONNECTED) 2] get /username
dongdong123
cZxid = 0x14
ctime = Thu Aug 02 14:56:38 CST 2018
mZxid = 0x1c
mtime = Thu Aug 02 22:01:10 CST 2018
pZxid = 0x14
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 11
numChildren = 0
也能够看出信息变为“dongdong123”了,说明测试成功!
4 集群模式安装
略,可参考Zookeeper入门看这篇就够了。