服务器动态上下线监听案例
需求
某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线。其实本质就是节点的创建和移除。
具体实现
1、先在集群上创建/servers 节点
2、编写服务端java代码
package dynamicSartedAndStop;
import org.apache.zookeeper.*;
import java.io.IOException;
/**
* Created by yazai
* Date: 22:32 2021/10/24
* Description:
*/
public class DistributeServer {
private static String connectString =
"192.168.80.18:2181,192.168.80.19:2181,192.168.80.20:2181";
private static int sessionTimeout = 200000;
private ZooKeeper zk = null;
private String parentNode = "/servers";
// 创建到 zk 的集群连接
public void getConnect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
public void process(WatchedEvent watchedEvent) {
}
});
}
// 注册服务器
public void registServer(String hostname) throws Exception {
String create = zk.create(parentNode + "/server",
hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(hostname + " is online " + create);
}
// 业务功能
public void business(String hostname) throws Exception {
//用sleep来模拟业务处理耗时
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]);
}
}
3、编写客户端java代码
package dynamicSartedAndStop;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by yazai
* Date: 22:45 2021/10/24
* Description:
*/
public class DistributeClient {
private static String connectString =
"192.168.80.18:2181,192.168.80.19:2181,192.168.80.20:2181";
//连接时间要设置长一点,不然会出现连接超时错误
private static int sessionTimeout = 200000;
private ZooKeeper zk = null;
private String parentNode = "/servers";
// 创建到 zk 的集群连接
public void getConnect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, new
Watcher() {
public void process(WatchedEvent event) {
// 再次启动监听
try {
getServerList();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
// 获取服务器列表信息
public void getServerList() throws Exception {
// 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);
}
// 业务功能
public void business() throws Exception {
System.out.println("client is working ...");
Thread.sleep(Long.MAX_VALUE);
}
public static void main(String[] args) throws Exception {
// 1 获取 zk 连接
DistributeClient client = new DistributeClient();
client.getConnect();
// 2 获取 servers 的子节点信息,从中获取服务器信息列表
client.getServerList();
// 3 业务进程启动
client.business();
}
}
测试
1、在 Linux 命令行上操作增加减少服务器
2、在 Idea 上操作增加减少服务器
(1)启动 DistributeClient 客户端(如果已经启动过,不需要重启)
(2)启动 DistributeServer 服务
①点击 Edit Configurations
②运行服务端代码
可以看到此时客户端监听到了我们指定的机器上线~