关于Zookeeper 的系统性学习推荐网址
http://www.cnblogs.com/sunddenly/p/4033574.html
一、Zookeeper的介绍
Zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。
之所以把本文归类为Dubbo是因为,博主关于Dubbo的学习笔记都是以Zookeeper作为注册中心的。
Zookeeper作为Dubbo服务的注册中心,Dubbo原先基于数据库的注册中心,没采用Zookeeper,Zookeeper一个分布式的服务框架,是树型的目录服务的数据存储,能做到集群管理数据 ,这里能很好的作为Dubbo服务的注册中心,Dubbo能与Zookeeper做到集群部署,当提供者出现断电等异常停机时,Zookeeper注册中心能自动删除提供者信息,当提供者重启时,能自动恢复注册数据。
关于Zookeeper的部署,但是在生产环境中,你最好部署3,5,7个节点。部署的越多,可靠性就越高。但是,我们作为本地自己熟练使用,部署一个就够了,部署一个Zookeeper是十分简单的。下面是单机部署Zookeeper的实例。
二、Zookeeper的部署
2.1、 ZooKeeper的下载
官网可下载:http://www.apache.org/dyn/closer.cgi/zookeeper/
当然,博主也将其上传到了csdn上了,下载更方便哦:http://download.csdn.net/detail/u013142781/9375686
2.2、配置
下载后解压,Zookeeper 的配置文件在 conf 目录下,有 zoo_sample.cfg 和 log4j.properties,将zoo_sample.cfg 重命名成zoo.cfg,因为 Zookeeper 在启动时会找这个文件作为默认配置文件。
下面介绍zoo.cfg文件里面几个配置的意义:
tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
我们需要进行的操作是修改dataDir这个配置的值,我们在Zookeeper的根目录下新建一个文件夹dataTmp,我的对应路径为:D:\zookeeper-3.4.6\dataTmp
修改配置文件对应地方为(注意一定是双\哦):
dataDir=D:\\zookeeper-3.4.6\\dataTmp
2.3、运行
启动Zookeeper目录下bin下的zkServer.cmd,我的是D:\Zookeepertest\zookeeper-3.4.6\bin\zkServer.cmd
:
启动之后一直开着,不要关掉这个cmd,记得要在Dubbo消费者和提供者运行之前就开启Zookeeper。

Maven:
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.3</version>
</dependency>
</dependencies>
相关代码:
// 创建一个与服务器的连接
ZooKeeper zk = new ZooKeeper("localhost:" + 2181, 5000, new Watcher() {
// 监控所有被触发的事件
public void process(WatchedEvent event) {
System.out.println(event.getPath() + "已经触发了" + event.getType() + "事件!");
}
});
List<String> t = zk.getChildren("/", true);
List<String> all = new ArrayList<String>();
for (String node : t) {
System.out.println("/" + node);
zk.delete("/" + node, -1);
}
// 创建一个目录节点
String res = zk.create("/testRootPath", "testRootData".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("====" + res);
// 创建一个子目录节点
res = zk.create("/testRootPath/testChildPathOne", "testChildDataOne".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(new String(zk.getData("/testRootPath", false, null)));
// 取出子目录节点列表
System.out.println(zk.getChildren("/testRootPath", true));
// 修改子目录节点数据
zk.setData("/testRootPath/testChildPathOne", "modifyChildDataOne".getBytes(), -1);
System.out.println("目录节点状态:[" + zk.exists("/testRootPath", true) + "]");
// 创建另外一个子目录节点
zk.create("/testRootPath/testChildPathTwo", "testChildDataTwo".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(new String(zk.getData("/testRootPath/testChildPathTwo", true, null)));
// 删除子目录节点
zk.delete("/testRootPath/testChildPathTwo", -1);
zk.delete("/testRootPath/testChildPathOne", -1);
// 删除父目录节点
zk.delete("/testRootPath", -1);
// 关闭连接
zk.close();
包含了:添加,删除,修改,查询(查询值以及查询子节点)
另:多次创建相同的路径会报错---同一个文件夹下不能包含两个相同文件名的文件