您的位置:首页 > 其它

zookeeper实时感知到主节点服务器的上下线

2017-08-18 19:33 405 查看
某分布式系统中,主节点可以有多台,可以动态上下线

任意一台客户端都能实时感知到主节点服务器的上下线

   思想就是当有一台上线时候  就创建一个临时 目录,向zk集群注册服务器信息  然后客户端就可去监听这个目录,如果这台机器挂掉了,那么监听到了一个事件,然后就知道了,这个机器下线了

如果这个客户端想使用这个服务器,那么可以用set   的方法  改变值,值为原来的值再加上自己的主机信息,那么这样就是实现负载均衡



 服务器 端:当来了一个客户端时候,就在 /servers下面注册一下

package cn.yzx.bigdata.zk;

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 DistributeedServer {
private static final String connectString="hadoop01:2181,hadoop02:2181,hadoop03:2181";
private static int sessionTimeout=2000;
private static final String parentNode="/servers";
private ZooKeeper zk=null;

//创建到zk的客户端连接
public void getConntect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {

@Override
public void process(WatchedEvent event) {
//收到事件通知后的回调函数(应该是我们自己的事件处理逻辑)
System.out.println(event.getType()+"--"+event.getPath());

//一下用来循环监听 因为正常监听一次又变化就不再监听
try {
zk.getChildren("/", true);
} catch (Exception e) {
}
}
});
}
/*
* 向zk集群注册服务器信息
*/
public void registerServer(String hostname) throws KeeperException, InterruptedException {
String create = zk.create(parentNode+"/server", hostname.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(hostname+" is online"+create);
}
/*
* 业务功能
*/
public void handleBussiness(String hostname) throws Exception {
System.out.println(hostname+" start working");
Thread.sleep(Long.MAX_VALUE);
}
public static void main(String[] args) throws Exception {
//获取zk连接
DistributeedServer server = new DistributeedServer();
server.getConntect();
//利用 zk连接注册服务器信息
server.registerServer("hadoop02");
// 启动业务功能
server.handleBussiness("hadoop02");
}
}


结果分析:
当客户端hadoop01 去连接的时候就会在zk集群注册  /servers/server000000000         get /servers/server0000000000      值为hadoop01

当客户端hadoop012去连接的时候就会在zk集群注册  /servers/server0000000001        get /servers/server0000000001      值为hadoop02

package cn.yzx.bigdata.zk;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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

public class DistributeClient {
private static final String connectString="hadoop01:2181,hadoop02:2181,hadoop03:2181";
private static int sessionTimeout=2000;
private static final String parentNode="/servers";
//为什么要加volatile?多线程值唯一:不会进行拷贝
private volatile List<String> serverList;
private ZooKeeper zk=null;

//创建到zk的客户端连接
public void getConntect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {

@Override
public void process(WatchedEvent event) {
//收到事件通知后的回调函数(应该是我们自己的事件处理逻辑)
try {
//重新更新服务器列表,并且注册了监听
getServerList();
} catch (Exception e) {
}
}
});
}
/*
* 获取服务器信息列表
*/
public void getServerList() throws Exception {
//获取服务器子节点信息,并且监听父节点
List<String> list = zk.getChildren(parentNode, true);
//先创建一个局部的list来存服务器信息
List<String> servers = new ArrayList<>();
for(String child :list) {

byte[] data = zk.getData(parentNode+"/"+child, false, null);
servers.add(new String(data));
}
//把servers赋值给成员变量serverList,以提供各业务线程使用
serverList=servers;

//打印一下服务器列表
System.out.println(serverList);
}

/*
* 业务功能
*/
public void handleBussiness() throws Exception {
System.out.println(" client start working");
}
public static void main(String[] args) throws Exception {
//获取zk连接
DistributeClient client = new DistributeClient();
client.getConntect();
//获取servers 的子节点的信息(并监听),从中获取服务器的信息列表
client.getServerList();
//业务线程启动
client.handleBussiness();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息