当前位置: 首页 > 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. 代码示例 在进行分…...

SpringBoot数据字典字段自动生成对应code和desc

效果&#xff1a;接口会返回orderType&#xff0c;但是这个orderType是枚举的类型&#xff08;1&#xff0c;2&#xff0c;3&#xff0c;4&#xff09;&#xff0c;我想多返回一个orderTypeDesc给前端展示&#xff0c;这样前端就可以直接拿orderTypeDesc使用了。 1. 定义注解 …...

TencentOS 2.4 final 安装mysql8.0备忘录

准备 tencentOS 2.4 与Red Hat Enterprise Linux 7 是兼容的。 我们首先从oracle官网上下载mysql的源文件。 下载完成后你会得到以下文件&#xff1a; mysql84-community-release-el7-1.noarch.rpm 安装 首先你需要切换到root用户下。 1.安装源文件 yum localinstall my…...

Hadoop HA安装配置(容器环境),大数据职业技能竞赛模块A平台搭建,jdk+zookeeper+hadoop HA

HA概述 &#xff08;1&#xff09; 所谓HA&#xff08;High Availablity&#xff09;,即高可用&#xff08;7*24小时不中断服务&#xff09;。 &#xff08;2&#xff09; 实现高可用最关键的策略是消除单点故障&#xff0c;HA严格来说应该分为各个组件的HA机制&#xff0c;H…...

使用javascript读取波形文件数据,并生成动态的波形图

代码如下&#xff1a; // HTML5 Canvas 动态波形生成器 // 使用JS读取波形文件并生成动态波形// 创建Canvas并设置上下文 const canvas document.createElement(canvas); canvas.width 800; canvas.height 400; document.body.appendChild(canvas); const ctx canvas.getC…...

服务器系统维护与安全配置

一、硬件系统的安全防护   硬件的安全问题也可以分为两种&#xff0c;一种是物理安全&#xff0c;一种是设置安全。   1、物理安全   物理安全是指防止意外事件或人为破坏具体的物理设备&#xff0c;如服务器、交换机、路由器、机柜、线路等。机房和机柜的钥匙一定要管理…...

大模型Weekly 03|OpenAI o3发布;DeepSeek-V3上线即开源!

大模型Weekly 03&#xff5c;OpenAI o3发布&#xff1b;DeepSeek-V3上线即开源&#xff01;DeepSeek-V3上线即开源&#xff1b;OpenAI 发布高级推理模型 o3https://mp.weixin.qq.com/s/9qU_zzIv9ibFdJZ5cTocOw?token47960959&langzh_CN 「青稞大模型Weekly」&#xff0c;持…...

Spring Boot自定义注解获取当前登录用户信息

写在前面 在项目开发过程中&#xff0c;难免都要获取当前登录用户的信息。通常的做法&#xff0c;都是开发一个获取用户信息的接口。 如果在本项目中&#xff0c;多处都需要获取登录用户的信息&#xff0c;难不成还要调用自己写的接口吗&#xff1f;显然不用&#xff01; 以…...

js创建二维空数组

js创建二维空数组 错误使用原因分析分析1举个例子&#xff1a;解释&#xff1a; 正确创建二维数组总结&#xff1a; 错误使用 今天在写代码的时候&#xff0c;需要创建一个长度为2的空二维数组&#xff0c;我当时第一反应就是&#xff0c;使用let arr new Array(2).fill([])&…...

AF3 checkpoint_blocks函数解读

checkpoint_blocks 函数实现了一种分块梯度检查点机制 (checkpoint_blocks),目的是通过分块(chunking)执行神经网络模块,减少内存使用。在深度学习训练中,梯度检查点(activation checkpointing)是一种显存优化技术。该代码可以: 对神经网络的块(blocks)按需分块,并对…...

下载并使用CICFlowMeter提取网络流特征(Windows版本)

CICFlowMeter简介 CICFlowMeter是一款流量特征提取工具&#xff0c;从原始的pcap包中聚合流&#xff0c;并提取流特征到csv格式的文件中。使用CICFlowMeter提取的特征有助于后续基于网络流的分析与建模 官方github地址&#xff1a;https://github.com/ahlashkari/CICFlowMete…...