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

ZooKeeper注册中心实现

具体步骤

  1. 安装ZooKeeper(启动端口占用,2181:客户端,8080:管理端)
  2. 引入客户端依赖
  3. 实现注册中心接口
  4. SPI补充ZooKeeper注册中心

引入依赖

<!-- zookeeper -->
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-x-discovery</artifactId><version>5.6.0</version>
</dependency>

ZooKeeper注册中心实现

/*** zookeeper 注册中心*/
public class ZooKeeperRegistry implements Registry {private static final Logger logger = LoggerFactory.getLogger(ZooKeeperRegistry.class);private CuratorFramework client;private ServiceDiscovery<ServiceMetaInfo> serviceDiscovery;/*** 本机注册的节点 key 集合(用于维护续期)*/private final Set<String> localRegisterNodeKeySet = new HashSet<>();/*** 注册中心服务缓存*/private final RegistryServiceMultiCache registryServiceMultiCache = new RegistryServiceMultiCache();/*** 正在监听的 key 集合*/private final Set<String> watchingKeySet = new ConcurrentHashSet<>();/*** 根节点*/private static final String ZK_ROOT_PATH = "/rpc/zk";@Overridepublic void init(RegistryConfig registryConfig) {// 构建 client 实例client = CuratorFrameworkFactory.builder().connectString(registryConfig.getAddress()).retryPolicy(new ExponentialBackoffRetry(Math.toIntExact(registryConfig.getTimeout()), 3)).build();// 构建 serviceDiscovery 实例serviceDiscovery = ServiceDiscoveryBuilder.builder(ServiceMetaInfo.class).client(client).basePath(ZK_ROOT_PATH).serializer(new JsonInstanceSerializer<>(ServiceMetaInfo.class)).build();try {// 启动 client 和 serviceDiscoveryclient.start();serviceDiscovery.start();} catch (Exception e) {throw new RuntimeException(e);}}@Overridepublic void register(ServiceMetaInfo serviceMetaInfo) throws Exception {// 注册到 zk 里serviceDiscovery.registerService(buildServiceInstance(serviceMetaInfo));// 添加节点信息到本地缓存String registerKey = ZK_ROOT_PATH + "/" + serviceMetaInfo.getServiceNodeKey();localRegisterNodeKeySet.add(registerKey);}@Overridepublic void unRegister(ServiceMetaInfo serviceMetaInfo) {try {serviceDiscovery.unregisterService(buildServiceInstance(serviceMetaInfo));} catch (Exception e) {throw new RuntimeException(e);}// 从本地缓存移除String registerKey = ZK_ROOT_PATH + "/" + serviceMetaInfo.getServiceNodeKey();localRegisterNodeKeySet.remove(registerKey);}@Overridepublic List<ServiceMetaInfo> serviceDiscovery(String serviceKey) {// 优先从缓存获取服务List<ServiceMetaInfo> cachedServiceMetaInfoList = registryServiceMultiCache.readCache(serviceKey);if (cachedServiceMetaInfoList != null) {return cachedServiceMetaInfoList;}try {// 查询服务信息Collection<ServiceInstance<ServiceMetaInfo>> serviceInstanceList = serviceDiscovery.queryForInstances(serviceKey);// 解析服务信息List<ServiceMetaInfo> serviceMetaInfoList = serviceInstanceList.stream().map(ServiceInstance::getPayload).collect(Collectors.toList());// 写入服务缓存registryServiceMultiCache.writeCache(serviceKey, serviceMetaInfoList);return serviceMetaInfoList;} catch (Exception e) {throw new RuntimeException("获取服务列表失败", e);}}@Overridepublic void heartBeat() {// 不需要心跳机制,建立了临时节点,如果服务器故障,则临时节点直接丢失}/*** 监听(消费端)** @param serviceNodeKey 服务节点 key*/@Overridepublic void watch(String serviceNodeKey) {String watchKey = ZK_ROOT_PATH + "/" + serviceNodeKey;boolean newWatch = watchingKeySet.add(watchKey);if (newWatch) {CuratorCache curatorCache = CuratorCache.build(client, watchKey);curatorCache.start();curatorCache.listenable().addListener(CuratorCacheListener.builder().forDeletes(childData -> registryServiceMultiCache.clearCache(serviceNodeKey)).forChanges(((oldNode, node) -> registryServiceMultiCache.clearCache(serviceNodeKey))).build());}}@Overridepublic void destroy() {logger.info("zookeeper注册中心下线...");// 下线节点(这一步可以不做,因为都是临时节点,服务下线,节点就被删掉)for (String key : localRegisterNodeKeySet) {try {client.delete().guaranteed().forPath(key);} catch (Exception e) {throw new RuntimeException(key + "节点下线失败");}}// 释放资源if (client != null) {client.close();}}private ServiceInstance<ServiceMetaInfo> buildServiceInstance(ServiceMetaInfo serviceMetaInfo) {String serviceAddress = serviceMetaInfo.getServiceHost() + ":" + serviceMetaInfo.getServicePort();try {return ServiceInstance.<ServiceMetaInfo>builder().id(serviceAddress).name(serviceMetaInfo.getServiceKey()).address(serviceAddress).payload(serviceMetaInfo).build();} catch (Exception e) {throw new RuntimeException(e);}}
}

添加SPI配置

etcd=com.starlink.registry.EtcdRegistry
zookeeper=com.starlink.registry.ZooKeeperRegistry

image-20241229170512331

最后配置文件指定ZooKeeper为注册中心即可使用ZooKeeper注册中心

rpc.registryConfig.registry=zookeeper
rpc.registryConfig.address=localhost:2181

相关文章:

ZooKeeper注册中心实现

具体步骤 安装ZooKeeper&#xff08;启动端口占用&#xff0c;2181&#xff1a;客户端&#xff0c;8080&#xff1a;管理端&#xff09;引入客户端依赖实现注册中心接口SPI补充ZooKeeper注册中心 引入依赖 <!-- zookeeper --> <dependency><groupId>org.a…...

数仓建模:如何进行实体建模?

目录 1 如何进行实体建模? 业务建模 领域建模 逻辑建模 2 实体建模具体步骤 需求分析...

Python编程技术

设计目的 该项目框架Scrapy可以让我们平时所学的技术整合旨在帮助学习者提高Python编程技能并熟悉基本概念&#xff1a; 1. 学习基本概念&#xff1a;介绍Python的基本概念&#xff0c;如变量、数据类型、条件语句、循环等。 2. 掌握基本编程技巧&#xff1a;教授学生如何使…...

「Mac玩转仓颉内测版55」应用篇2 - 使用函数实现更复杂的计算

本篇教程基于仓颉编程语言扩展了计算器功能&#xff0c;支持加减乘除的基础运算&#xff0c;以及幂运算和开平方等高级功能。代码经过简化后&#xff0c;移除了对输入的复杂校验&#xff0c;提升了程序的可维护性和交互效率。 关键词 仓颉编程语言函数封装高级运算 一、功能说…...

map参数详解

const items new Array(15).fill(null).map((_, index) > ({key: index 1,label: nav ${index 1}, })); $.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性)&#xff0c;并将处理结果封装为新的数组返回。 注意&#xff1a;1. 在jQuery 1.6 之前&#…...

OSI 七层模型 | TCP/IP 四层模型

注&#xff1a;本文为 “OSI 七层模型 | TCP/IP 四层模型” 相关文章合辑。 未整理去重。 OSI 参考模型&#xff08;七层模型&#xff09; BeretSEC 于 2020-04-02 15:54:37 发布 OSI 的概念 七层模型&#xff0c;亦称 OSI&#xff08;Open System Interconnection&#xf…...

高转速风扇|无刷暴力风扇方案设计

在当今科技高速发展的时代&#xff0c;电子设备的性能不断提升&#xff0c;散热问题也日益成为关注的焦点。而 13w 高转速暴力风扇方案的出现&#xff0c;为解决各种设备的散热难题提供了强大的技术支持。 一、高转速暴力风扇的重要性 随着电子设备的不断升级&#xff0c;其功率…...

GPU 进阶笔记(三):华为 NPU/GPU 演进

大家读完觉得有意义记得关注和点赞&#xff01;&#xff01;&#xff01; 1 术语 1.1 CPU1.2 GPU1.3 NPU / TPU1.4 小结2 华为 DaVinci 架构&#xff1a;一种方案覆盖所有算力场景 2.1 场景、算力需求和解决方案2.2 Ascend NPU 设计3 路线一&#xff1a;NPU 用在手机芯片&…...

计算机网络 (13)信道复用技术

前言 计算机网络中的信道复用技术是一种提高网络资源利用率的关键技术。它允许在一条物理信道上同时传输多个用户的信号&#xff0c;从而提高了信道的传输效率和带宽利用率。 一、信道复用技术的定义 信道复用&#xff08;Multiplexing&#xff09;就是在一条传输媒体上同时传输…...

数据库约束和查询

一 约束意义 这个后面的字段是什么意思呢? 先前说数据类型是一种约束&#xff0c;约束我们只能放该类型的数据&#xff0c;还有其它的约束来保证数据的合法性&#xff0c;下面的字段就和约束有关。 编译器的编译就是一个约束&#xff0c;保证我们的代码一定是语法合格的。我们…...

网工日记:FTP两种工作模式的区别

FTP 的主动模式和被动模式在连接建立的发起方、数据传输端口以及对网络环境的适应性等方面存在明显区别&#xff1a; 1. 连接发起方 主动模式&#xff1a;数据连接由服务器主动发起。在控制连接建立后&#xff0c;客户端通过 PORT 命令告知服务器自己用于接收数据的临时端口号…...

NLP模型工程化部署

文章目录 一、理论-微服务、测试与GPU1&#xff09;微服务架构2&#xff09;代码测试3&#xff09;GPU使用 二、实践-封装微服务&#xff0c;编写测试用例和脚本&#xff0c;并观察GPU1&#xff09;微服务封装(RestFul和RPC)2&#xff09;测试编写(unit_test\api_test\load_tes…...

分布式版本管理工具——git 中忽略文件的版本跟踪(初级方法及高级方法)

git工具忽略指定文件的版本跟踪 一、简单方式实现二、复杂方式实现&#xff08;模式匹配&#xff09;1. 相关规则2. 应用案例a) 忽略所有内容b) 忽略所有目录&#xff08;不忽略当前目录的具体文件&#xff09;c)忽略指定目录下的所有文件&#xff0c;但排除某文件d&#xff09…...

【LangChain】Chapter4 - Question and Answer Over Documents

说在前面 文档问答&#xff0c;是常见的一类LLM应用&#xff0c;给定一段可能是从 PDF文件、网页或某公司内部文档库中提取的文本&#xff0c;使用LLM回答关于这些文档内容的问题。这样的应用非常的强大&#xff0c;它可以将LLM与完全没被训练的数据相结合&#xff0c;可以灵活…...

TCP/IP 协议演进中的瓶颈,权衡和突破

所有(去掉 “几乎” 修饰)问题都来自于生长速度的不一致&#xff0c;换句话说&#xff0c;膨胀不是均匀的&#xff0c;从而产生瓶颈甚至触碰极限&#xff0c;TCP/IP 从协议到实现面临的多方问题与动物体型不能无限大&#xff0c;摩天大楼不能无限高本质上一样。 如今被高性能网…...

软件测试面试八股文,查漏补缺(附文档)

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;准备面试了&#xff0c;又不知道从何下手&#xff01;为了帮大家节约时间&#xff0c;特意准备了一份面试相关的资料&#xff0c;内容非常的全面&#xff0c;真的可以好好补一补&#xff0c;希望大家在都能拿到理想的…...

IDEA工具使用介绍、IDEA常用设置以及如何集成Git版本控制工具

文章目录 一、IDEA二、建立第一个 Java 程序三、IDEA 常用设置四、IDEA 集成版本控制工具&#xff08;Git、GitHub&#xff09;4.1 IDEA 拉 GitHub/Git 项目4.2 IDEA 上传 项目到 Git4.3 更新提交命令 一、IDEA 1、什么是IDEA&#xff1f; IDEA&#xff0c;全称为 IntelliJ ID…...

YOLOv10-1.1部分代码阅读笔记-transformer.py

transformer.py ultralytics\nn\modules\transformer.py 目录 transformer.py 1.所需的库和模块 2.class TransformerEncoderLayer(nn.Module): 3.class AIFI(TransformerEncoderLayer): 4.class TransformerLayer(nn.Module): 5.class TransformerBlock(nn.Module)…...

机器人革新!ModbusTCP转CCLINKIE网关揭秘

在当今这个科技日新月异的时代&#xff0c;机器人技术正以前所未有的速度发展着&#xff0c;它们在工业制造、医疗服务、家庭娱乐等多个领域扮演着越来越重要的角色。而随着机器人应用的普及和多样化&#xff0c;如何实现不同设备之间的高效通信成为了一个亟待解决的问题。开疆…...

JWT包中的源码分析【Golang】

前言 最近在学web编程的途中&#xff0c;经过学长提醒&#xff0c;在进行登陆&#xff08;Login&#xff09;操作之后&#xff0c;识别是否登陆的标识应该要放入authorization中&#xff0c;正好最近也在学鉴权&#xff0c;就顺便来看看源码了。 正文 1. 代码示例 在进行分…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

《Offer来了:Java面试核心知识点精讲》大纲

文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...

Axure零基础跟我学:展开与收回

亲爱的小伙伴,如有帮助请订阅专栏!跟着老师每课一练,系统学习Axure交互设计课程! Axure产品经理精品视频课https://edu.csdn.net/course/detail/40420 课程主题:Axure菜单展开与收回 课程视频:...