zookeeper感知服务器节点动态上下线案例

半城伤御伤魂 提交于 2020-01-17 05:30:17

大家好,我是AC,下面是关于zookeeper的一个案例,供练习
关于zookeeper,请看上一篇文章

在这里插入图片描述
1)需求:某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线
2)需求分析

3)具体实现:
(0)先在集群上创建/servers节点

[zk: localhost:2181(CONNECTED) 10] create /servers "servers"

Created /servers

(1)服务器端代码

package com.bigdata.anli;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

public class RegistServer {
	
	private ZooKeeper client = null;
	String connectString = "hadoop101:2181";
	int sessionTimeout = 2000;
	String parentPath = "/servers";
	
	
	public static void main(String[] args) throws Exception {
		RegistServer server = new RegistServer();
		//1 获取zookeeper集群客户端
		server.getClient();
		//2 在zookeeper集群上创建临时节点,其内容是:注册登录服务器的地址
		server.regist(args[0]);
		//3 开启自己的业务方法
		server.dowork(args[0]);
		
	}
	
	private void dowork(String hostname) throws Exception {
		System.err.println(hostname+"开始工作了");
		//模拟服务器永不关机
		Thread.sleep(Long.MAX_VALUE);
	}

	private void regist(String hostname) throws Exception, Exception {
		//要在/servers节点下创建子节点
		String create = client.create(parentPath+"/"+hostname, hostname.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
		System.err.println(hostname+"上线了");
	}

	public void getClient() throws Exception {
		//第一个参数:要连接要zookeeper的地址和端口号
		//第二个参数:连接的超时时间
		//第三个参数:观察者
		client = new ZooKeeper(connectString , sessionTimeout , new Watcher() {
			
			//这是回调方法,zookeeper发现数据或者子节点发生变化后,则会以调用该方法的形式来通知我
			// WatchedEvent event 这里面就封装了变化的详细信息
			//这里要写我们自己的业务逻辑
			public void process(WatchedEvent event) {
				
			}
		});
	}
	
}

(2)客户端代码

package com.bigdata.anli;

import java.util.List;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

public class StudyServer {
	
	private ZooKeeper client = null;
	String connectString = "hadoop101:2181";
	int sessionTimeout = 2000;
	String parentPath = "/servers";
	List<String> servers = null;
	
	public static void main(String[] args) throws Exception {
		StudyServer server = new StudyServer();
		//1 获取zookeeper的客户端
		server.getClient();
		//2 获取/servers的子节点(注册登录服务器的地址)并委托zookeeper集群监听/servers子节点的增减
		server.getServerList();
		//3 开始自己的业务工作
		server.dowork();
	}
	
	
	private void dowork() throws Exception {
		for (String hostname : servers) {
			System.err.println("使用"+hostname+"开始干活");
		}
		Thread.sleep(Long.MAX_VALUE);
	}


	private void getServerList() throws Exception, Exception {
		List<String> children = client.getChildren(parentPath, true);
		for (String hostname : children) {
			System.err.println("获取到注册登录服务器地址:"+hostname);
		}
		servers = children;
	}


	public void getClient() throws Exception {
		//第一个参数:要连接要zookeeper的地址和端口号
		//第二个参数:连接的超时时间
		//第三个参数:观察者
		client = new ZooKeeper(connectString , sessionTimeout , new Watcher() {
			
			//这是回调方法,zookeeper发现数据或者子节点发生变化后,则会以调用该方法的形式来通知我
			// WatchedEvent event 这里面就封装了变化的详细信息
			//这里要写我们自己的业务逻辑
			public void process(WatchedEvent event) {
				try {
					//子节点发生变化后,zookeeper会来通知我,我们会再次获取子节点,并且再次委托zookeeper进行监听
					getServerList();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}
	

}

有问题,多多指正,谢谢

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!