基于Zookeeper服务注册和发现

1、项目的目录结构


2、基于zk服务注册和发现的架构图

      

3、服务端(像zk提供服务的访问地址)

package cn.zk.distribute;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

public class DistributedSystemServer {

	private ZooKeeper zk = null;

	private void getZkClient() throws Exception {

		// 服务器在需求中并不需要做任何监听
		zk = new ZooKeeper(GlobalConstants.zkhosts,
				GlobalConstants.sessionTimeout, null);

	}

	/**
	 * 向zookeeper中的/servers下创建子节点
	 * 
	 * @throws InterruptedException
	 * @throws KeeperException
	 */
	private void connectZK(String serverName, String port) throws Exception {

		// 先创建出父节点
		if (zk.exists(GlobalConstants.parentZnodePath, false) == null) {
			zk.create(GlobalConstants.parentZnodePath, null,
					Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
		}

		// 连接zk创建znode
		zk.create(GlobalConstants.parentZnodePath + "/",
				(serverName + ":" + port).getBytes(), Ids.OPEN_ACL_UNSAFE,
				CreateMode.EPHEMERAL_SEQUENTIAL);
		System.out.println("server " + serverName + " is online ......");

	}

	// 服务器的具体业务处理功能
	private void handle(String serverName) throws Exception {
		System.out.println("server " + serverName
				+ " is waiting for task process......");
		Thread.sleep(Long.MAX_VALUE);

	}

	public static void main(String[] args) throws Exception {

		DistributedSystemServer server = new DistributedSystemServer();

		// 获取与zookeeper通信的客户端连接
		server.getZkClient();

		// 一启动就去zookeeper上注册服务器信息,参数1: 服务器的主机名 参数2:服务器的监听端口
		server.connectZK(args[0], args[1]);

		// 进入业务逻辑处理流程
		server.handle(args[0]);

	}

}

2、客户端(获取zk提供的服务地址,并调用服务)

package cn.zk.distribute;

import java.util.ArrayList;
import java.util.List;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.Watcher.Event.EventType;

public class DistributedSystemClient {

	private volatile List<String> servers = null;
	private ZooKeeper zk = null;

	// 获取zk连接
	private void getZkClient() throws Exception {

		// 服务器在需求中并不需要做任何监听
		zk = new ZooKeeper(GlobalConstants.zkhosts,
				GlobalConstants.sessionTimeout, new Watcher() {

					@Override
					public void process(WatchedEvent event) {

						if (event.getType() == EventType.None)
							return;

						try {
							// 获取新的服务器列表,重新注册监听
							updateServers();

						} catch (Exception e) {

							e.printStackTrace();
						}

					}
				});

	}

	/**
	 * 从zk中获取在线服务器信息
	 */
	public void updateServers() throws Exception {

		// 从servers父节点下获取到所有子节点,并注册监听
		List<String> children = zk.getChildren(GlobalConstants.parentZnodePath,
				true);

		ArrayList<String> serverList = new ArrayList<String>();

		for (String child : children) {

			byte[] data = zk.getData(GlobalConstants.parentZnodePath + "/"
					+ child, false, null);

			serverList.add(new String(data));

		}

		// 如果客户端是一个多线程程序,而且各个线程都会竞争访问servers列表,所以,在成员中用volatile修饰了一个servers变量
		// 而在更新服务器信息的这个方法中,是用一个临时List变量来进行更新
		servers = serverList;

		// 将更新之后的服务器列表信息打印在控制台观察一下
		for (String server : serverList) {

			System.out.println(server);
		}
		System.out.println("===================");

	}

	/**
	 * 业务逻辑
	 * 
	 * @throws InterruptedException
	 */
	private void requestService() throws InterruptedException {
		Thread.sleep(Long.MAX_VALUE);

	}

	public static void main(String[] args) throws Exception {

		DistributedSystemClient client = new DistributedSystemClient();

		// 先构造一个zk的连接
		client.getZkClient();

		// 获取服务器列表
		client.updateServers();

		// 客户端进入业务流程,请求服务器的服务
		client.requestService();

	}

}

3、用到的常量配置信息

package cn.zk.distribute;

public class GlobalConstants {
	// zk服务器列表
	public static final String zkhosts = "192.168.2.118:2181";
	// 连接的超时时间
	public static final int sessionTimeout = 2000;
	// 服务在zk下的路径
	public static final String parentZnodePath = "/servers";

}

4、将服务端,导出为可以运行的jar文件

      

      

       

jar的运行

[root@localhost Desktop]# java -jar server.jar 192.168.2.11 4567

5、将客户端,导出为可以运行的jar文件

      步骤与上面的4相同,可以参照上面的步骤过程。    

7、源码下载

链接:http://pan.baidu.com/s/1eRHHGBK 密码:9d90


  • 8
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值