zookeeper的应用在
http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/index.html
上已经列举出来,本文根据自己业务需要,实现了公司的统一命名服务。
统一命名服务(Name Service)
分布式应用中,通常需要有一套完整的命名规则,既能够产生唯一的名称又便于人识别和记住,通常情况下用树形的名称结构是一个理想的选择,树形的名称结构是一个有层次的目录结构,既对人友好又不会重复。说到这里你可能想到了 JNDI,没错 Zookeeper 的 Name Service 与 JNDI 能够完成的功能是差不多的,它们都是将有层次的目录结构关联到一定资源上,但是 Zookeeper 的 Name Service 更加是广泛意义上的关联,也许你并不需要将名称关联到特定资源上,你可能只需要一个不会重复名称,就像数据库中产生一个唯一的数字主键一样。
Name Service 已经是 Zookeeper 内置的功能,你只要调用 Zookeeper 的 API 就能实现。如调用 create 接口就可以很容易创建一个目录节点。
在zk系统中创建的节点可以保证在分布式服务器上是全局唯一的。
命名服务提供注册、注销和查看命名等接口。
命名服务的关键逻辑
- /**
- * 标题:统一命名服务
- * 作者:
- * 时间:2013-04-17
- * 描述:提供了Naming类,给分布式程序开发人员或其一个分布式全局唯一的命名。
- */
- package com.my.nameservice;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.zookeeper.CreateMode;
- import org.apache.zookeeper.KeeperException;
- import org.apache.zookeeper.ZooKeeper;
- import org.apache.zookeeper.ZooDefs.Ids;
- public class Naming {
- private ZooKeeper zk = null; // ZooKeeper对象
- private String nameroot = "/NameService";
- private String namerootvalue = "IsNameService";
- private String namevalue = "IsName";
- /**
- * @函数:命名服务构造函数
- * @参数:zk的地址端口 描述:初始化zk实例,创建命名服务根路径
- */
- public Naming(String url) {
- try {
- // 初始化,如果当前有alive的zk连接则先关闭
- if (zk != null && zk.getState().isAlive() == true)
- zk.close();
- zk = new ZooKeeper(url, 30000, null); // 重新建立连接
- System.out.println("zookeeper connect success:url=" + url);
- } catch (Exception e) {
- e.printStackTrace();
- }
- // 判断是否有/NameService,如果没有,则创建该路径,用来作为所有的集中配置信息的根目录
- try {
- if (zk.exists(nameroot, false) == null) {
- zk.create(nameroot, namerootvalue.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
- System.out.println(nameroot + " create success!");
- }
- } catch (KeeperException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- System.out.println(e.getMessage());
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- System.out.println(e.getMessage());
- }
- }
- /**
- * @函数: 注销zk实例
- */
- public void UnNaming() {
- if (zk != null) {
- try {
- zk.close();
- System.out.println("zookeeper close success!");
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- System.out.println(e.getMessage());
- }
- zk = null;
- }
- }
- /**
- * @函数:注册一个全局名字
- * @描述:待注册的名字字符串name,在zk中创建一个/NameService/name的znode路径
- * @参数: 待注册的名字字符串name
- * @返回值: 0 表示注册成功 -1 表示出错 1 表示该命名已被注册
- */
- @SuppressWarnings("finally")
- public int Registered(String name) {
- String path = nameroot + "/" + name;
- int ret = 0;
- try {
- if (zk.exists(path, false) == null) {
- zk.create(path, namevalue.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
- System.out.println(name + " registered success!");
- } else {
- ret = 1;
- System.out.println(name + " is exists, can not regist again!");
- }
- } catch (KeeperException e) {
- // TODO Auto-generated catch block
- ret = -1;
- e.printStackTrace();
- System.out.println(e.getMessage());
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- ret = -1;
- e.printStackTrace();
- System.out.println(e.getMessage());
- } finally {
- return ret;
- }
- }
- /**
- * @函数:注销一个全局名字
- * @描述:待注销的名字字符串name,在zk中删除/NameService/name的znode路径
- * @参数: 待注销的名字字符串name
- * @返回值: 0 表示注销成功 -1 表示出错 1 表示该命名未注册,不存在命名服务系统中
- */
- @SuppressWarnings("finally")
- public int Canceled(String name) {
- String path = nameroot + "/" + name;
- int ret = 0;
- try {
- if (zk.exists(path, false) != null) {
- zk.delete(path, -1);
- System.out.println(name + " canceled success!");
- } else {
- ret = 1;
- System.out.println(name + " is not exists, can not canceled!");
- }
- } catch (KeeperException e) {
- // TODO Auto-generated catch block
- ret = -1;
- e.printStackTrace();
- System.out.println(e.getMessage());
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- ret = -1;
- e.printStackTrace();
- System.out.println(e.getMessage());
- } finally {
- return ret;
- }
- }
- /**
- * @函数:获取命名服务系统的所有命名
- * @描述:
- * @参数:
- * @返回值:命名列表
- */
- public List<String> Readall() {
- List<String> namelist = new ArrayList<String>();
- try {
- namelist = zk.getChildren(nameroot, false);
- } catch (KeeperException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return namelist;
- }
- }