一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情。
比如我们现在进行项目的分布式部署,现在假设我们有两台机器,我们的客户端要去请求对应的机器,根据负载我们假如轮询,会不停请求这两台机器,但是如果有一台机器掉线或者有一台机器上线,我们都应该做出判断请求的流向, 当然这个功能有很多方式都可以实现,我这里恰好ZK罢了;
首先我们要create一个根节点,用于我们下面的测试,这里我就给个/server吧;给个监听的create方法里我们将spring.application.name的名字当做子节点,存的key也存我们的应用名吧;给一个完全开放的ACL;ZooDefs.Ids.OPEN_ACL_UNSAFE;
然后指定要创建的节点是临时的还是持久的,CreateMode.EPHEMERAL_SEQUENTIAL,这个表示znode会在客户端断开连接时被删除,并且它的名字会附加一个单调递增的数字(我这次测试用),PERSISTENT_SEQUENTIAL,客户端断开连接时znode不会被自动删除,它的名字会附加一个单调递增的数字; PERSISTENT,客户端断开连接时不会自动删除znode,就说这三个吧;
@Bean
public void initZkBean() throws IOException {
zkClient = new ZooKeeper(address, timeout, new Watcher() {
@SneakyThrows
@Override
public void process(WatchedEvent watchedEvent) {
if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
String create = zkClient.create( "/server"+"/"+hostName, hostName.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
log.info(hostName+"创建"+create);
} } });
System.out.println("zookeeper初始化状态" + zkClient.getState());
}
在业务方法里我们获取根节点的子节点,监听设为true;
List<String> childrens = ZooKeeper.getZkBean().getChildren("/server", true);
System.out.println("存在的节点是:");
childrens.stream().forEach(System.out::println);
这样我们就可以获取到我们的子节点信息了,对应了就可以获取到我们的服务信息了,也就是我们的服务有没有停了,首先我们在服务器上getAllChildrenNumber /server看有几个子节点;然后启动项目,我本地起了一个,云服务器起了一个,两个服务看看;
只起一个服务查出来结果:
存在的节点是:
mycommon0000000009
接着我们起第二个服务
出来个11不知道哪个部分又create了,不过没事,我们现在开始停服务;先把本地的停了,等一会继续查询有几个子节点,09的节点就掉了,但是云服务的出现了12;
好像是节点的变动会触发监听,而我的create是写在监听里的,只需把create挪出来即可,对就是这样的,对于服务器端启动项目的命令是nohup java -jar springboot-1.0-SNAPSHOT.jar -Dspring.config.location=application.yaml &;这里注意application.yaml要和项目在同一路径下,不然得指定路径;
这样我们就算实现了监听服务上下限的判断啦!