利用zookeeper实现分布式运用服务器上下线的动态感知-简单程序

来源:互联网 发布:海岩是双性恋 知乎 编辑:程序博客网 时间:2024/06/05 11:20

简要分析:

1、服务器端将自己注册到zookeeper上,使用临时性序列节点

2、客户端通过zookeeper获取服务器端的状态信息


//1、服务器端代码

package cn.nyzc.testzk;

import java.io.IOException;
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 TestZK01 {


private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
int sessionTimeout = 2000;
ZooKeeper zkServer;
private String parentPath = "/servers";


//main方法。当作启动的线程
public static void main(String[] args) throws Exception {
TestZK01 zk01=new TestZK01();
//1 创建连接
zk01.inintZK();
//2 注册服务器
zk01.register(args[0]);
//3 业务方法
zk01.business(args[0]);
}

//创建连接
public void inintZK() throws IOException {
zkServer = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
}
});
}


// 注册服务器
public void register(String hostname) throws Exception {
// 往zookeeper上新建一个临时节点
String create = zkServer.create(parentPath + "/server", hostname.getBytes(), 
Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTIAL);
// 打印一下
System.out.println(hostname + " is on line " + create);
}

//业务方法
public void business(String hostname) throws Exception{
System.out.println(hostname+" is working!");
//线程等待
Thread.sleep(Long.MAX_VALUE);
}


}


//======================================


//2、客户端代码


package cn.nyzc.testzk;


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 TestZK02 {

private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
int sessionTimeout = 2000;
ZooKeeper client;
private String parentPath = "/servers";
//线程公用,且不允许拷贝到线程栈区
private volatile List<String> serversList = new ArrayList<>();


//main方法。当作主线程
public static void main(String[] args) throws Exception {
TestZK02 zk02 = new TestZK02();
// 1创建连接
zk02.getConnect();
// 2 获取/servers下子节点信息
zk02.getServerList();
// 3 业务进程启动
zk02.business();
}


// 创建连接
public void getConnect() throws IOException {
client = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
//监听事件调用方法(一个监听调用一次)
@Override
public void process(WatchedEvent event) {
try {
getServerList();
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
}
});
}

// 获取/servers下的子节点信息
public void getServerList() throws KeeperException, InterruptedException {
// 获取路径下的所有子节点
List<String> children = client.getChildren(parentPath, true);


List<String> servers = new ArrayList<>();
for (String child : children) {
// 获取具体子节点的内容
byte[] data = client.getData(parentPath + "/" + child, false, null);
servers.add(new String(data));
}
//把数据装入到公用集合中
serversList = servers;
System.out.println(serversList);
}


// 业务功能
public void business() throws Exception {
System.out.println("client is working ...");
Thread.sleep(Long.MAX_VALUE);
}


}