在前几篇博客中,介绍的是使用 zookeeper 原生提供的 API 来编程的方法,其实,在 curator 出来之后,
使用 zookeeper 原生态 API 编程的方法就被很多人抛弃不用了。
在前面的文章中也简单的介绍了在一个 linux 主机上,通过配置多端口来部署一个"伪分布式" zookeeper 集群系统,
对于编写客户端的代码而言,单节点和"伪分布式" 两者并没有太大的区别。
在这里之所以使用单节点部署 zookeeper 服务器端的原因是最新稳定版本的 zookeeper 也就是 3.4.6 版本中,
有一个安全性的检查,如果配置不慎,很有可能触发安全性检测的日志打印,而这个安全性的检查将它的日志写到的异常中,
这就会出现,当 zookeeper 服务器进程启动之后,使用 zkCli.sh 启动客户端连接服务器端,会无休止的在控制台中
打印出异常信息,仔细看信息的话,就会发现全部是 WARN 级别的信息,但是却无法让使用者在命令端输入任何命令。
所以,出于这种原因,在这里介绍一下单点部署 zookeeper 的编程开发环境。
1. 将 zookeeper 安装包下载到路径 /usr/local 下,并解压压缩文件包
并将 zookeeper-3.*.* 修改成为 zookeeper (为了配置文件书写起来方便一些)
2. 复制 ../conf/路径下面的配置文件模板 zoo_sample.cfg ,将其命名为 zoo.cfg ,
修改 ../conf/路径下面的 zoo.cfg ,如下所示,
注意 dataDir 路径的设置是 "/usr/local/zookeeper/data" ,那么在系统的对应路径下面要创建一个 data 文件夹

3. 修改了配置文件之后,接下来我们开始修改系统环境文件,在/etc/profile 文件结尾追加如下内容

4. 接着启动 zookeeper 服务器端 / zkServer.sh
将路径切换到 zoo.cfg 所在的路径下面, 由于 zookeeper 的bin 路径已经被添加到系统 PATH 中,
所以 zkServer.sh 会被系统自动的定位到 /usr/local/zookeeper/bin/ 的下面的。
[命令] ./zkServer.sh start ./zoo.cfg
[命令|检测 zk server 是否运行] ps -aux | grep "zookeeper"
[输出]

5. 接着启动 zookeeper 的客户端 / zkCli.sh
[命令] ./zkCli.sh
[输出]

6. 接着启动 linu 上的 IDE , 创建一个 maven module 项目
6.1 修改 pom.xml 在其中添加 curator(zookeeper 客户端) 的依赖
点击(此处)折叠或打开
-
<dependencies>
-
<dependency>
-
<groupId>org.apache.curator</groupId>
-
<artifactId>curator-framework</artifactId>
-
<version>2.7.0</version>
-
</dependency>
-
<dependency>
-
<groupId>org.apache.curator</groupId>
-
<artifactId>curator-recipes</artifactId>
-
<version>2.7.0</version>
-
</dependency>
-
<dependency>
-
<groupId>org.apache.curator</groupId>
-
<artifactId>curator-test</artifactId>
-
<version>2.7.0</version>
-
</dependency>
-
-
<dependency>
-
<groupId>org.apache.zookeeper</groupId>
-
<artifactId>zookeeper</artifactId>
-
<version>3.4.6</version>
-
</dependency>
-
-
- </dependencies>
点击(此处)折叠或打开
-
package org.kylin;
-
-
/**
-
* Created with IntelliJ IDEA.
-
* User: root
-
* Date: 7/24/15
-
* Time: 11:02 PM
-
* To change this template use File | Settings | File Templates.
-
*/
-
-
import org.apache.curator.utils.CloseableUtils ;
-
import org.apache.curator.framework.CuratorFramework ;
-
import org.apache.curator.framework.CuratorFrameworkFactory ;
-
import org.apache.curator.framework.recipes.cache.ChildData ;
-
import org.apache.curator.framework.recipes.cache.PathChildrenCache ;
-
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent ;
-
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener ;
-
import org.apache.curator.retry.ExponentialBackoffRetry;
-
import org.apache.curator.utils.ZKPaths ;
-
-
public class SubPathChangeInvoker
-
{
-
private static final String main_path = "/MainPath" ;
-
-
public static void main ( String args [] ) throws Exception
-
{
-
CuratorFramework client = null ;
-
PathChildrenCache cache = null ;
-
-
try
-
{
-
client = CuratorFrameworkFactory.builder()
-
.connectString("127.0.0.1:2181")
-
.sessionTimeoutMs(3000)
-
.connectionTimeoutMs(3000)
-
.canBeReadOnly(false)
-
.retryPolicy( new ExponentialBackoffRetry(1000 , Integer.MAX_VALUE))
-
-
.defaultData("aimer".getBytes())
-
.build() ;
-
client.start() ;
-
-
System.out.println(" client running ") ;
-
-
// first we create the main path
-
client.create().forPath(main_path) ;
-
-
-
cache = new PathChildrenCache( client , main_path , true ) ;
-
cache.start() ;
-
-
// we add the listener inside the cache
-
cache.getListenable().addListener( addListenerToPathChildrenCache() );
-
-
// the listener and the events already registered inside in the PathChildrenCache's instance
-
// we let the IDE program wait for a while , and during this period we do some create, update , delete
-
// by zkCli.sh
-
// see what happens in this IDE program 's output
-
Thread.sleep(6000);
-
-
System.out.println("here we gonna create two sub nodes") ;
-
client.create().forPath(main_path+"/node1" , "node1".getBytes()) ;
-
client.create().forPath(main_path+"/node2", "node2".getBytes()) ;
-
-
-
System.out.println("delete the two sub nodes , we just create ") ;
-
client.delete().forPath(main_path+"/node1") ;
-
client.delete().forPath(main_path+"/node2") ;
-
-
-
System.out.println("here we gonna a loop for a very long time , do something on zkCli !") ;
-
-
while( true ) ;
-
-
-
}
-
finally
-
{
-
// close and relase resources in order
-
CloseableUtils.closeQuietly(cache); ;
-
CloseableUtils.closeQuietly(client);
-
-
}
-
-
}
-
-
private static PathChildrenCacheListener addListenerToPathChildrenCache ( )
-
{
-
// in this method , we first create an interface object which contain events
-
// invoke to different evnets , and then pass the interface : PathChildrenCacheListener
-
// into the cache this class instance
-
-
// if you refer to the api of the PathChildrenCacheListener , you will find there is one method
-
// with the name of childEvent declared in it , given / write the method for this method
-
// when the passed in cache finds out something happend to it the corresponding method will be called
-
// by different kinds of events {child add , child node remove , child node's data updated }
-
-
-
PathChildrenCacheListener listener = new PathChildrenCacheListener() {
-
@Override
-
public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent childEvent)
-
throws Exception
-
{
-
-
System.out.println("i am in childEvent ") ;
-
-
switch (childEvent.getType() )
-
{
-
case CHILD_ADDED:
-
{
-
System.out.println("Node added : " + ZKPaths.getNodeFromPath(childEvent.getData().getPath() )) ;
-
System.out.println("Node data is : "+ new String (childEvent.getData().getData() ) ) ;
-
-
-
Thread.sleep(1000);
-
break ;
-
}
-
case CHILD_UPDATED:
-
{
-
System.out.println("Node updated : " +ZKPaths.getNodeFromPath(childEvent.getData().getPath() )) ;
-
System.out.println("Node data is (new ): " + new String (childEvent.getData().getData())) ;
-
-
-
break ;
-
}
-
case CHILD_REMOVED:
-
{
-
System.out.println("Node removed : " +ZKPaths.getNodeFromPath(childEvent.getData().getPath())) ;
-
break ;
-
}
-
}
-
-
}
-
} ; // new an instance of interface , remember add ";" at the end
-
-
// we have created a listener , now we add the listener into the cache object
-
return listener ;
-
-
}
- }
6.3 在 zookeeper 客户端命令行中, 进行创建指定目录下面的子节点,删除子节点,更新子节点上的数据
在 zkCli 控制台中输入命令

6.4 查看 IDE 环境中的输出结果

手动退出,毕竟设定的是 while 死循环,后续的博客中会简单介绍使用 netty + zk 进行多各节点的网络编程/如果编译顺利的话.
end