欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ZooKeeper之服务器动态上下线案例

程序员文章站 2022-04-21 17:28:33
需求 某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线。 需求分析 具体实现 先在集群上创建/servers节点 create /servers "servers" 一些依赖 pom.xml: 在src/main/resources下添加一个file ......

需求

某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线。

需求分析

ZooKeeper之服务器动态上下线案例

 

 

具体实现

先在集群上创建/servers节点

create /servers "servers"

一些依赖

pom.xml:

<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelversion>4.0.0</modelversion>
  <groupid>com.mcq</groupid>
  <artifactid>zookeeper1026</artifactid>
  <version>0.0.1-snapshot</version>
  <dependencies>
		<dependency>
			<groupid>junit</groupid>
			<artifactid>junit</artifactid>
			<version>release</version>
		</dependency>
		<dependency>
			<groupid>org.apache.logging.log4j</groupid>
			<artifactid>log4j-core</artifactid>
			<version>2.8.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
		<dependency>
			<groupid>org.apache.zookeeper</groupid>
			<artifactid>zookeeper</artifactid>
			<version>3.4.10</version>
		</dependency>
</dependencies>
</project>

 在src/main/resources下添加一个file log4j.properties:

log4j.rootlogger=info, stdout  
log4j.appender.stdout=org.apache.log4j.consoleappender  
log4j.appender.stdout.layout=org.apache.log4j.patternlayout  
log4j.appender.stdout.layout.conversionpattern=%d %p [%c] - %m%n  
log4j.appender.logfile=org.apache.log4j.fileappender  
log4j.appender.logfile.file=target/spring.log  
log4j.appender.logfile.layout=org.apache.log4j.patternlayout  
log4j.appender.logfile.layout.conversionpattern=%d %p [%c] - %m%n

 

服务器端向 zookeeper 注册代码

package com.mcq.zookeeper1026;

import java.io.ioexception;

import org.apache.zookeeper.createmode;
import org.apache.zookeeper.keeperexception;
import org.apache.zookeeper.watchedevent;
import org.apache.zookeeper.watcher;
import org.apache.zookeeper.zoodefs.ids;
import org.apache.zookeeper.zookeeper;

public class distributeserver {
	private string connectstring = "hadoop103:2181,hadoop104:2181,hadoop105:2181";
	private int sessiontimeout = 2000;
	private zookeeper zk = null;
	private string parentnode = "/servers";

	public void getconnect() throws ioexception {
		zk = new zookeeper(connectstring, sessiontimeout, new watcher() {

			@override
			public void process(watchedevent event) {
				// todo auto-generated method stub

			}

		});
	}

	// 注册服务器
	public void registserver(string hostname) throws exception {
		system.out.println(zk);
		string path = zk.create(parentnode + "/server", hostname.getbytes(), ids.open_acl_unsafe,
				createmode.ephemeral_sequential);
		system.out.println(hostname + " is online " + path);
	}

	// 业务功能
	public void business(string hostname) throws interruptedexception {
		system.out.println(hostname + " is working ……");
		thread.sleep(long.max_value);
	}

	public static void main(string[] args) throws exception {
		// 1.获取zk连接
		distributeserver server = new distributeserver();
		server.getconnect();
		// 2.利用zk连接注册服务器信息
		server.registserver(args[0]);
		// 3.启动业务功能
		server.business(args[0]);

	}
}

 

客户端代码

package com.mcq.zookeeper1026;

import java.io.ioexception;
import java.util.arraylist;
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 distributeclient {
	public static void main(string[] args) throws ioexception, keeperexception, interruptedexception {
		//1.获取zk连接
		distributeclient client=new distributeclient();
		client.getconnect();
		//2.获取servers的子节点信息,从中获取服务器信息列表
		client.getserverlist();
		//3.业务进程启动
		client.business();
	}

	private void business() throws interruptedexception {
		// todo auto-generated method stub
		system.out.println("client is working ……");
		thread.sleep(long.max_value);
	}

	private string parentnode="/servers";

	private void getserverlist() throws keeperexception, interruptedexception {
		// todo auto-generated method stub
		//1.获取服务器子节点信息,并且对父节点进行监听
		list<string> children = zk.getchildren(parentnode,true);
		//2.存储服务器信息列表
		arraylist<string> servers=new arraylist<>();
		//3.遍历所有节点,获取节点中的主机名称信息
		for(string child:children) {
			byte[] data=zk.getdata(parentnode+"/"+child,false,null);
			servers.add(new string(data));
		}
		//4.打印服务器列表信息
		system.out.println(servers);
	}

	private zookeeper zk=null;
	private string connectstring="hadoop103:2181,hadoop104:2181,hadoop105:2181";
	private int sessiontimeout=2000;

	private void getconnect() throws ioexception {
		// todo auto-generated method stub
		//创建到zk的客户端连接
		zk=new zookeeper(connectstring,sessiontimeout,new watcher() {

			@override
			public void process(watchedevent event) {
				// todo auto-generated method stub
				try {
					getserverlist();
				}catch(exception e) {
					e.printstacktrace();
				}
			}
			
		});
	}
}

 

运行程序

先运行客户端

在xshell上登录客户端(bin/zkcli.sh),进行一些操作,可以看到eclipse的控制台会实时输出有哪些节点。

ZooKeeper之服务器动态上下线案例

 

然后运行服务器端,记得先在run configuration里设置一下参数,比如设成hadoop103,那么运行后,客户端的控制台会实时显示当前的节点。

ZooKeeper之服务器动态上下线案例

 

 点上面那个红框可以切换控制台。