1.需求
某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线。
2.需求分析
3.具体实现
(0)先在集群上创建/servers节点:
[zk: localhost:2181(CONNECTED) 10] create /servers "servers" Created /servers
(1)服务器端向Zookeeper注册代码:
import org.apache.zookeeper.*; import org.jetbrains.annotations.NotNull; import java.io.IOException; public class DistributeServer { public static void main(@NotNull String[] args) throws IOException, KeeperException, InterruptedException { DistributeServer server = new DistributeServer(); // 思路:先写大框架!在考虑细节 // 1.连接zookeeper集群 server.getConnect(); // 2.注册节点 server.regist(args[0]); // 3.业务逻辑处理 server.business(); } private void business() throws InterruptedException { // 睡眠,保证进程不结束 Thread.sleep(Long.MAX_VALUE); } private void regist(String hostname) throws KeeperException, InterruptedException { // 由于每次注册只调用下面这一个方法,故设置CreateMode时只能设置临时带序号的类型 zkClient.create("/servers/server",hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); System.out.println(hostname + " is online !"); } private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181"; private int sessionTimeout = 2000; private ZooKeeper zkClient;//客户端对象 private void getConnect() throws IOException { zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() { public void process(WatchedEvent event) { } }); } }
(2)客户端代码
import org.apache.zookeeper.KeeperException; 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; public class DistributeClient { private String connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181"; private int sessionTimeout = 2000; private ZooKeeper zkClient;//客户端对象 public static void main(String[] args) throws IOException, KeeperException, InterruptedException { DistributeClient client = new DistributeClient(); // 1.获取zookeeper集群连接 client.getConnect(); // 2. 注册监听 client.getChildren(); // 3.业务逻辑处理 client.business(); } private void business() throws InterruptedException { Thread.sleep(Long.MAX_VALUE); } private void getChildren() throws KeeperException, InterruptedException { // 监听/servers 启动监听之后会进入new Watcher()的process方法中 List<String> children = zkClient.getChildren("/servers", true); // 存储服务器节点主机的名称,放在集合里 ArrayList<String> hosts = new ArrayList<String>();; for (String child : children) { // 拼接可得要获得的数据目的地 byte[] data = zkClient.getData("/servers/" + child, false, null); hosts.add(new String(data)); } // 将所有在线主机名称打印到控制台 System.out.println(hosts); } private void getConnect() throws IOException { zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() { public void process(WatchedEvent event) { System.out.println("启用的监听!"); // 如果不将下面的代码放在此处,那么监听只会执行一次 try { // 为了动态监听 getChildren(); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }); } }
要记得在运行时候main中args[ ]要事先配置哦!