三, 利用Zookeeper实现 服务器动态上下线
三, 利用Zookeeper实现 服务器动态上下线
3.1 需求
- 在某分布式系统中, 主节点可以有多台, 可以动态上下线, 任意一台客户端都能
实时感知到主节点服务器的上下线
.
3.2 需求分析
3.3 具体实现
- 先在集群上创建/servers 节点
[zk: localhost:2181(CONNECTED) 0] create /servers "servers"
Created /servers
-
IDEA中创建包名
cn.qsc.zkcase1
-
新建java类,
DistributeServer.java
如果对于某些方法的实现有疑问, 参见前面文章中zookeeper的API操作-3.3 小节
/**
* 服务器端的实现功能:
* 1. 与zk集群进行连接
* 2. 注册服务器到zk集群(即在zk集群中建立临时的代表服务器在线的节点)
* 3. 实现服务器的一些运行逻辑(直接让服务器休眠以避免程序过快结束, 以后我们可以在这里面实现一些复杂的业务逻辑)
*/
public class DistributeServer {
private static String connectString = "bigdata01:2181,bigdata02:2181,bigdata03:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zk;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
DistributeServer server = new DistributeServer();
//1. 获取zk连接
server.getConnect();
//2. 注册服务器到集群(在zk集群中创建znode节点, 节点的值就是上线的服务器名称)
server.register(args[0]);
//3. 实现服务器的一些运行逻辑
//休眠, 避免程序立马就结束
server.business();
}
private void business() throws InterruptedException {
Thread.sleep(Long.MAX_VALUE);
}
private void register(String hostname) throws InterruptedException, KeeperException {
//创建临时的带序号的znode节点, 这个节点的数据就是服务器的名称
zk.create("/servers/"+hostname, hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(hostname + " is online now");
}
private void getConnect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
//监听器的一些实现逻辑
}
});
}
}
- 新建java类,
DistributeClient.java
/**
* 客户端的实现功能:
* 1. 与zk集群进行连接
* 2. 监听zk集群 /servers 路径下节点的增加和减少变化(代表着服务器的上线和下线), ls -w /servers
* 3. 实现客户端的一些运行逻辑(直接让客户端休眠以避免程序过快结束, 以后我们可以在这里面实现一些复杂的业务逻辑)
*/
public class DistributeClient {
private static String connectString = "bigdata01:2181,bigdata02:2181,bigdata03:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zk;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
DistributeClient client = new DistributeClient();
//1. 与zk集群进行连接
client.getConnect();
//2. 建立监听器
client.getServerList();
//3. 业务逻辑(休眠)
client.business();
}
private void business() throws InterruptedException {
Thread.sleep(Long.MAX_VALUE);
}
private void getServerList() throws InterruptedException, KeeperException {
List<String> servers = zk.getChildren("/servers", true);
List<String> serverData = new ArrayList<>();
for (String server : servers) {
//获取路径下的节点数据并存放到集合中去
//易错点: 拼接子节点!!!!
byte[] data = zk.getData("/servers/"+server, false, null);
//data封装为String对象, 然后存放到集合中;
serverData.add(new String(data));
}
//直接输出集合, 显示znode节点内容(上线服务器信息)
System.out.println(serverData);
}
private void getConnect() throws IOException {
zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
try {
getServerList();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
}
}
});
}
}
3.4 测试
- 对客户端实现类, DistributeClient, 单独测试如下
- 开启客户端实现类DistributeClient的同时, 开启服务器端实现类DistributeServer, 并做以下操作:
-
1.配置
-
- 传入参数
- 传入参数
-
- 启动DistributeServer, 控制台应该有方框中的内容
- 启动DistributeServer, 控制台应该有方框中的内容
-
- 同时DistributeClient的控制台会同步显示出上面我们加入的参数
- 同时DistributeClient的控制台会同步显示出上面我们加入的参数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)