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;
	}

}



Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐