手撸RPC框架---服务注册

文章介绍了如何使用Zookeeper进行服务注册和发现的过程,包括创建ZooKeeper实例、节点操作以及封装工具类。同时,提出项目可扩展至其他注册中心,如Nacos和Redis,通过Registry接口实现抽象能力。
摘要由CSDN通过智能技术生成

一、服务注册和发现具体流程

1、服务提供方将服务注册到注册中心中。

2、消费端拉取服务列表。

3、消费端简单的选取一个可以服务(后续会进行改造,实现负载均衡)。

为了让注册和拉取相对更加简单,我们封装了相应的工具类,代码如下:

@Slf4j
public class ZookeeperUtils {
    
    
    /**
     * 使用默认配置创建zookeeper实例
     * @return zookeeper实例
     */
    public static ZooKeeper createZookeeper(){
        // 定义连接参数
        String connectString = Constant.DEFAULT_ZK_CONNECT;
        // 定义超时时间
        int timeout = Constant.TIME_OUT;
        return createZookeeper(connectString,timeout);
    }
    
    public static ZooKeeper createZookeeper(String connectString,int timeout){
        CountDownLatch countDownLatch = new CountDownLatch(1);
        try {
            // 创建zookeeper实例,建立连接
            final ZooKeeper zooKeeper = new ZooKeeper(connectString, timeout, event -> {
                // 只有连接成功才放行
                if (event.getState() == Watcher.Event.KeeperState.SyncConnected) {
                    log.debug("客户端已经连接成功。");
                    countDownLatch.countDown();
                }
            });
        
            countDownLatch.await();
            return zooKeeper;
        } catch (IOException  | InterruptedException e) {
            log.error("创建zookeeper实例时发生异常:",e);
            throw new ZookeeperException();
        }
    }
    
    /**
     * 创建一个节点的工具方法
     * @param zooKeeper zooKeeper实例
     * @param node 节点
     * @param watcher watcher实例
     * @param createMode 节点的类型
     * @return true: 成功创建  false: 已经存在  异常:抛出
     */
    public static Boolean createNode(ZooKeeper zooKeeper,ZookeeperNode node,Watcher watcher,CreateMode createMode){
        try {
            if (zooKeeper.exists(node.getNodePath(), watcher) == null) {
                String result = zooKeeper.create(node.getNodePath(), node.getData(),
                    ZooDefs.Ids.OPEN_ACL_UNSAFE, createMode);
                log.info("节点【{}】,成功创建。",result);
                return true;
            } else {
                if(log.isDebugEnabled()){
                    log.info("节点【{}】已经存在,无需创建。",node.getNodePath());
                }
                return false;
            }
        } catch (KeeperException| InterruptedException e) {
            log.error("创建基础目录时发生异常:",e);
            throw new ZookeeperException();
        }
    }
    
    /**
     * 判断节点是否存在
     * @param zk zk实例
     * @param node  节点路径
     * @param watcher watcher
     * @return ture 存在 | false 不存在
     */
    public static boolean exists(ZooKeeper zk,String node,Watcher watcher){
        try {
            return zk.exists(node,watcher) != null;
        } catch (KeeperException | InterruptedException e) {
            log.error("判断节点[{}]是否存在时发生异常",node,e);
            throw new ZookeeperException(e);
        }
    }
    
    /**
     * 关闭zookeeper的方法
     * @param zooKeeper zooKeeper实例
     */
    public static void close(ZooKeeper zooKeeper){
        try {
            zooKeeper.close();
        } catch (InterruptedException e) {
            log.error("关闭zookeeper时发生问题:",e);
            throw new ZookeeperException();
        }
    }
    
    /**
     * 查询一个节点的子元素
     * @param zooKeeper zk实例
     * @param serviceNode 服务节点
     * @return 子元素列表
     */
    public static List<String> getChildren(ZooKeeper zooKeeper, String serviceNode,Watcher watcher) {
        try {
            return zooKeeper.getChildren(serviceNode, watcher);
        } catch (KeeperException | InterruptedException e) {
            log.error("获取节点【{}】的子元素时发生异常.",serviceNode,e);
            throw new ZookeeperException(e);
        }
    }
}

二、抽象能力

当前项目中我们的确使用的是zookeeper作为我们项目的注册中心。但是,我们希望在我们的项目是可以扩展使用其他类型的注册中心的,如nacos,redis,甚至是自己独立开发注册中心。

public interface Registry {
    
    /**
     * 注册服务
     * @param serviceConfig 服务的配置内容
     */
    void register(ServiceConfig<?> serviceConfig);
    
    /**
     * 从注册中心拉取服务列表
     * @param serviceName 服务的名称
     * @return 服务的地址
     */
    List<InetSocketAddress> lookup(String serviceName,String group);
    
}

目录结构:

针对注册中心的核心能力,我们抽象出简洁核心的接口,这样需要其他的扩展仅仅需要完成独立的实现即可完成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值