zookeeper快速入门五:用zookeeper实现服务注册与发现中心

系列:

zookeeper快速入门一:zookeeper安装与启动-CSDN博客

zookeeper快速入门二:zookeeper基本概念-CSDN博客

zookeeper快速入门三:zookeeper的基本操作

zookeeper快速入门四:在java客户端中操作zookeeper-CSDN博客


经过前面四章的讲解,我们已经对zookeeper建立起初步的概念,这篇文章就来做一个小小的实践,用zookeeper实现一个简单版的服务注册与发现中心。

zookeeper的一个常见功能就是作为服务注册与发现中心。

我们先创建一个节点/services。

java 复制代码
        Stat stat = zkClient.exists("/services",false);
        if (stat == null ){
            zkClient.create("/services","".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }

每当有一个服务上线时,我们就向我们的服务注册与发现中心zookeeper注册我们的应用。

比如,我们注册一个user服务,服务地址是localhost:8080,那么我们就在/services下面建立一个user子节点,子节点数据为user服务的真实url地址,比如localhost:8080,子节点类型为临时节点。

java 复制代码
    public void registerService()throws Exception{
        zkClient.create("/services/user","localhost:8080".getBytes(),
                ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);

    }

当我们向user请求服务时,首先通过/services节点获取user服务,判断user服务是否存在。进而获取它的地址,发起真正的请求。同时,我们注册一个监听事件,监听节点的状态变化。当user服务出现故障或其他因素而下线时,/services/user节点会被删除,zookeeper server会通知到监听这个节点的客户端,从而使客户端做出自己的响应,同样的,当user服务上线或地址修改,客户端也能收到通知。

java 复制代码
    public void invokeUserService()throws Exception{
        Stat stat = zkClient.exists("/services/user",false);
        if (stat == null){
            System.out.println("未能找到user服务,服务未注册或已下线");
        }
        byte[] url = zkClient.getData("/services/user", new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                if (watchedEvent.getType() == Event.EventType.NodeDeleted){
                    System.out.println("服务下线");
//                    处理业务逻辑
                }
                if (watchedEvent.getType() == Event.EventType.NodeCreated){
                    System.out.println("服务上线");
//                    处理业务逻辑
                }
                if (watchedEvent.getType() == Event.EventType.NodeDataChanged){
                    System.out.println("服务地址修改了");
                }
            }
        }, null);
//        处理业务逻辑
         System.out.println("向"+new String(url)+"发起请求");
    }

如果对前面有印象的话,应该记得zookeeper的watcher只触发一次,当节点状态改变一次之后,节点状态的第二次改变就不能监听到了。为了能够持续监听,我们需要修改一下我们的代码。

我们把判断服务上线的代码挪到上面来,并且在下面的监听事件里回调invokeUserService方法,实现持续监听的功能。

为了简单易懂,这里代码写得并不够好,如果是实际项目,需要再做点拆分与封装。

java 复制代码
    public void invokeUserService()throws Exception{
        Stat stat = zkClient.exists("/services/user",false);
        if (stat == null){
            System.out.println("未能找到user服务,服务未注册或已下线");
            zkClient.exists("/services/user", new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {
                    if (watchedEvent.getType() == Event.EventType.NodeCreated){
                        System.out.println("服务上线");
//                    处理业务逻辑
                    }
                }
            });
        }else{
            byte[] url = zkClient.getData("/services/user", new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {
                    if (watchedEvent.getType() == Event.EventType.NodeDeleted){
                        System.out.println("服务下线");
//                    处理业务逻辑
                    }
                    if (watchedEvent.getType() == Event.EventType.NodeDataChanged){
                        System.out.println("服务地址修改了");
                    }
                    try {
                        invokeUserService();
                    }catch (Exception e){

                    }
                }
            }, null);
//        处理业务逻辑
            System.out.println("向"+new String(url)+"发起请求");
        }

    }

zookeeper作为一个分布式协调框架,它的创建就是为了方便或者简化分布式应用的开发。除了服务注册与发现之外,它还能够提供更多的功能,但是对于入门来说,简单的了解到这里就已经足够了。下面会讲zookeeper的架构设计与原理,比如zookeeper的原子协议,leader选举算法等。

相关推荐
极客先躯11 分钟前
如何自动提取Git指定时间段的修改文件?Win/Linux双平台解决方案
linux·git·elasticsearch
suijishengchengde1 小时前
****LINUX时间同步配置*****
linux·运维
qiuqyue1 小时前
基于虹软Linux Pro SDK的多路RTSP流并发接入、解码与帧级处理实践
linux·运维·网络
切糕师学AI1 小时前
Linux 操作系统简介
linux
南烟斋..2 小时前
GDB调试核心指南
linux·服务器
爱跑马的程序员2 小时前
Linux 如何查看文件夹的大小(du、df、ls、find)
linux·运维·ubuntu
oMcLin4 小时前
如何在 Ubuntu 22.04 LTS 上部署并优化 Magento 电商平台,提升高并发请求的响应速度与稳定性?
linux·运维·ubuntu
Qinti_mm5 小时前
Linux io_uring:高性能异步I/O革命
linux·i/o·io_uring
优雅的38度5 小时前
linux环境下,使用docker安装apache kafka (docker-compose)
linux·架构
想唱rap5 小时前
表的约束条件
linux·数据库·mysql·ubuntu·bash