当前位置: 首页 > article >正文

Dubbo自定义扩展注册中心

Registry

在 服务发现 一章中,我们了解了 Dubbo 内置的几个核心注册中心实现 NacosZookeeper 的使用方式与工作原理。本文讲解如何通过扩展 org.apache.dubbo.registry.client.ServiceDiscovery 和 org.apache.dubbo.registry.nacos.NacosServiceDiscoveryFactory SPI,提供自定义的注册中心实现。

本示例的完整源码请参见 dubbo-registry-etcd。除了本示例之外,Dubbo 核心仓库 apache/dubbo 以及扩展库 apache/dubbo-spi-extensions 中的众多注册中心扩展实现,都可以作为扩展参考实现:

# Dubbo对外支持的常用注册中心实现
nacos=org.apache.dubbo.registry.nacos.NacosServiceDiscoveryFactory
zookeeper=org.apache.dubbo.registry.zookeeper.ZookeeperServiceDiscoveryFactory

任务详情

通过扩展 SPI 实现基于的 etcd 注册中心。

实现方式

代码详情

首先,通过继承 AbstractServiceDiscoveryFactory 实现 ServiceDiscoveryFactory 接口

public class EtcdServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory {

    @Override
    protected ServiceDiscovery createDiscovery(URL registryURL) {
        return new EtcdServiceDiscovery(applicationModel, registryURL);
    }

}

EtcdServiceDiscovery 的一些关键方法与实现如下:

public class EtcdServiceDiscovery extends AbstractServiceDiscovery {

    private final Set<String> services = new ConcurrentHashSet<>();
    private final Map<String, InstanceChildListener> childListenerMap = new ConcurrentHashMap<>();

    EtcdClient etcdClient;

    public EtcdServiceDiscovery(ApplicationModel applicationModel, URL registryURL) {
        super(applicationModel, registryURL);
        EtcdTransporter etcdTransporter = applicationModel.getExtensionLoader(EtcdTransporter.class).getAdaptiveExtension();

        etcdClient = etcdTransporter.connect(registryURL);

        etcdClient.addStateListener(state -> {
            if (state == StateListener.CONNECTED) {
                try {
                    recover();
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
        });

        this.registryURL = registryURL;
    }

    @Override
    public void doRegister(ServiceInstance serviceInstance) {
        try {
            String path = toPath(serviceInstance);
            etcdClient.putEphemeral(path, new Gson().toJson(serviceInstance));
            services.add(serviceInstance.getServiceName());
        } catch (Throwable e) {
            throw new RpcException("Failed to register " + serviceInstance + " to etcd " + etcdClient.getUrl()
                + ", cause: " + (OptionUtil.isProtocolError(e)
                ? "etcd3 registry may not be supported yet or etcd3 registry is not available."
                : e.getMessage()), e);
        }
    }

    @Override
    protected void doUnregister(ServiceInstance serviceInstance) {
        try {
            String path = toPath(serviceInstance);
            etcdClient.delete(path);
            services.remove(serviceInstance.getServiceName());
        } catch (Throwable e) {
            throw new RpcException("Failed to unregister " + serviceInstance + " to etcd " + etcdClient.getUrl() + ", cause: " + e.getMessage(), e);
        }
    }

    @Override
    public void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener) throws NullPointerException, IllegalArgumentException {
        for (String serviceName : listener.getServiceNames()) {
            registerServiceWatcher(serviceName, listener);
        }
    }

    @Override
    public List<ServiceInstance> getInstances(String serviceName) {
        List<String> children = etcdClient.getChildren(toParentPath(serviceName));
        if (CollectionUtils.isEmpty(children)) {
            return Collections.emptyList();
        }
        List<ServiceInstance> list = new ArrayList<>(children.size());
        for (String child : children) {
            ServiceInstance serviceInstance = new Gson().fromJson(etcdClient.getKVValue(child), DefaultServiceInstance.class);
            list.add(serviceInstance);
        }
        return list;
    }
}

SPI配置

在 resources/META-INF/dubbo/org.apache.dubbo.registry.client.ServiceDiscoveryFactory 文件中添加如下配置:

etcd=org.apache.dubbo.registry.etcd.EtcdServiceDiscoveryFactory

使用方式

要开启 etcd 作为注册中心,修改应用中的 resources/application.properties 文件中的 registry 配置如下:

dubbo.registry.address=etcd://host:port

 


http://www.kler.cn/a/401851.html

相关文章:

  • 完整http服务器
  • python: generator IDAL and DAL using sql server 2019
  • 关于安卓模拟器或手机设置了BurpSuite代理和安装证书后仍然抓取不到APP数据包的解决办法
  • 初识进程——Linux
  • MySQL安装及数据库基础
  • 基于YOLOv8深度学习的独居老人情感状态监护系统(PyQt5界面+数据集+训练代码)
  • Jav项目实战II基于微信小程序的助农扶贫的设计与实现(开发文档+数据库+源码)
  • 数据结构(二)线性表
  • 助力模型训练,深度学习的经典数据集介绍
  • Matplotlib | 理解直方图中bins表示的数据含义
  • WPF 中 MultiConverter ——XAML中复杂传参方式
  • 推荐一款UI/UX原型设计工具:Icons8 Lunacy
  • 【Rust 学习笔记】Rust 安装与 “Hello World” 程序介绍
  • qt中ctrl+鼠标左键无法进入
  • MFC图形函数学习09——画多边形函数
  • 【小程序】dialog组件
  • PHP批量操作加锁
  • CSP/信奥赛C++语法基础刷题训练(16):洛谷P5731:蛇形方阵
  • C++11——异常
  • 网络安全检测技术
  • python用哈希删除文件夹中重复的图片
  • linux配置动态ip
  • 网络--网络层协议--IP
  • ARM CCA机密计算安全模型之生态
  • hhdb数据库介绍(9-24)
  • SpringBoot 增量部署发布(第2版)