ZooKeeper之服务器动态上下线案例
程序员文章站
2022-04-21 17:28:33
需求 某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线。 需求分析 具体实现 先在集群上创建/servers节点 create /servers "servers" 一些依赖 pom.xml: 在src/main/resources下添加一个file ......
需求
某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线。
需求分析
具体实现
先在集群上创建/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的控制台会实时输出有哪些节点。
然后运行服务器端,记得先在run configuration里设置一下参数,比如设成hadoop103,那么运行后,客户端的控制台会实时显示当前的节点。
点上面那个红框可以切换控制台。
上一篇: MySQL索引查询原理