在 Kubernetes 为主流注册发现的今天,给出如何在 Spring Boot 中基于 ZooKeeper 实现服务注册/发现、分布式锁、配置中心以及集群协调的完整代码与最佳实践。所有示例均可直接复制运行。


1. ZooKeeper 架构与核心原理

1.1 角色

  • Leader:处理写请求,广播事务(ZAB 协议)。
  • Follower / Observer:处理读请求,Follower 参与选举,Observer 仅扩展读能力。

1.2 一致性协议:ZAB(ZooKeeper Atomic Broadcast)

  1. 所有写请求统一由 Leader 生成全局递增的 zxid
  2. 两阶段提交(Proposal → ACK → Commit)。
  3. 崩溃恢复阶段:根据 zxid 选举新 Leader,保证已 Commit 的事务不丢失。

1.3 数据模型

/
├── services
│   ├── user-service
│   │   ├── 192.168.1.10#8080  (EPHEMERAL_SEQUENTIAL)
│   │   └── 192.168.1.11#8080
│   └── order-service
├── configs
│   └── application.yml
└── locks├── pay_lock_0000000001 (EPHEMERAL_SEQUENTIAL)└── pay_lock_0000000002
  • EPHEMERAL:会话断则节点自动删除,天然适合心跳/服务实例。
  • SEQUENTIAL:节点名后缀自增,用于公平锁、队列。

2. Spring Boot 集成 ZooKeeper

场景:K8s 已有 Service 发现,但团队需要异构语言互通强一致配置分布式锁,于是引入 ZooKeeper。

2.1 依赖

<dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>5.5.0</version>
</dependency>
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-x-discovery</artifactId><version>5.5.0</version>
</dependency>
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>5.5.0</version>
</dependency>

2.2 自动配置(Spring Boot 3.x)

@Configuration
@EnableConfigurationProperties(ZkProps.class)
public class ZkConfig {@Bean(initMethod = "start", destroyMethod = "close")public CuratorFramework curator(ZkProps p) {return CuratorFrameworkFactory.builder().connectString(p.getUrl()).sessionTimeoutMs(30_000).connectionTimeoutMs(10_000).retryPolicy(new ExponentialBackoffRetry(1000, 3)).build();}@Beanpublic ServiceDiscovery<InstanceDetails> discovery(CuratorFramework client) throws Exception {ServiceDiscovery<InstanceDetails> sd = ServiceDiscoveryBuilder.builder(InstanceDetails.class).client(client).basePath("/services").serializer(new JsonInstanceSerializer<>(InstanceDetails.class)).build();sd.start();return sd;}
}

2.3 服务注册(应用启动时自动注册)

@Component
@RequiredArgsConstructor
public class ZkRegistrar implements ApplicationRunner {private final ServiceDiscovery<InstanceDetails> discovery;private final ZkProps props;@Overridepublic void run(ApplicationArguments args) throws Exception {InstanceDetails payload = new InstanceDetails(props.getProfile());ServiceInstance<InstanceDetails> instance = ServiceInstance.<InstanceDetails>builder().name(props.getAppName()).id(props.getPodIp() + ":" + props.getPort()).address(props.getPodIp()).port(props.getPort()).payload(payload).build();discovery.registerService(instance);}
}

2.4 服务发现(负载均衡示例)

@Component
@RequiredArgsConstructor
public class ZkLoadBalancer {private final ServiceDiscovery<InstanceDetails> discovery;public InstanceDetails choose(String serviceName) throws Exception {Collection<ServiceInstance<InstanceDetails>> instances =discovery.queryForInstances(serviceName);if (instances.isEmpty()) throw new IllegalStateException("No instances");// 轮询return instances.stream().skip(ThreadLocalRandom.current().nextInt(instances.size())).findFirst().orElseThrow().getPayload();}
}

3. 分布式锁:Curator Recipes

Curator 提供 InterProcessMutex(可重入)、InterProcessSemaphoreMutex(不可重入)等实现。

3.1 配置

@Bean
public InterProcessMutex payLock(CuratorFramework client) {return new InterProcessMutex(client, "/locks/pay");
}

3.2 业务中使用

@Service
@RequiredArgsConstructor
public class PayService {private final InterProcessMutex payLock;public void pay(String orderId) throws Exception {if (payLock.acquire(10, TimeUnit.SECONDS)) {try {// 幂等扣款逻辑} finally {payLock.release();}} else {throw new RuntimeException("获取锁超时");}}
}

3.3 高级:读写锁

@Bean
public InterProcessReadWriteLock rwLock(CuratorFramework client) {return new InterProcessReadWriteLock(client, "/locks/rw");
}

4. 配置中心(动态刷新)

4.1 存储

/configs/application.yml

4.2 监听与热更新

@Component
@RequiredArgsConstructor
public class ConfigWatcher {private final CuratorFramework client;private final Environment env;@PostConstructpublic void watch() throws Exception {TreeCache cache = TreeCache.newBuilder(client, "/configs").build();cache.getListenable().addListener((cf, event) -> {if (event.getType() == TreeCacheEvent.Type.NODE_UPDATED) {String path = event.getData().getPath();if (path.endsWith("application.yml")) {byte[] data = event.getData().getData();// 这里触发 Spring Environment 刷新((ConfigurableEnvironment) env).getPropertySources().replace("zk-config", new MapPropertySource("zk-config",new Yaml().load(new String(data))));}}});cache.start();}
}

5. 最佳实践与注意事项

维度建议
部署3 或 5 节点奇数集群,独立 SSD,JVM 堆 4-8G,开启快照自动清理。
会话会话超时 < 客户端 GC 时间;避免长时间 STW。
节点数据节点 < 1MB,子节点 < 10 万;使用 Observer 扩展读。
锁路径独立;锁内逻辑幂等、可重试;设置超时避免死锁。
K8sStatefulSet 部署 ZooKeeper;Headless Service 使 Pod 稳定 DNS。
迁移若未来迁到 etcd,可通过 Curator-to-etcd Bridge 逐步替换。

6. 小结

功能K8s 原生ZooKeeper 方案优势
服务发现CoreDNS跨语言、精细权重、健康检查可扩展
分布式锁强一致、可重入、读写锁
配置中心ConfigMap监听粒度细、版本化、变更审计
集群协调Leader 选举、队列、屏障(Barrier)

K8s 为主的今天,ZooKeeper 并非过时,而是作为强一致协调层的补充,特别适合金融交易、库存扣减、大规模异构系统


参考阅读

  • Curator 官方文档
  • ZooKeeper Internals

如需进一步探讨性能压测脚本K8s Operator 部署方案,欢迎留言!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/917644.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/917644.shtml
英文地址,请注明出处:http://en.pswp.cn/news/917644.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

可验证随机函数-VRF

可验证随机函数&#xff08;Verifiable Random Function, VRF&#xff09;是一种结合密码学技术的伪随机数生成器&#xff0c;其核心特点是生成的随机数可被公开验证&#xff0c;且具有不可预测性和唯一性。以下是VRF的详细解析&#xff1a;1. 基本定义与核心特性 可验证性&…

极客大挑战2020(部分wp)

Roamphp1-Welcome 405请求方法不允许&#xff0c;改一下请求方法 数组绕过&#xff0c;在页面搜索flag即可&#xff01;本题&#xff1a;就是知道了405是请求方法不允许&#xff01; Roamphp2-Myblog&#xff08;zip协议加文件包含&#xff09; 首先进来就是一个博客页面&…

ESP32 外设驱动开发指南 (ESP-IDF框架)——GPIO篇:基础配置、外部中断与PWM(LEDC模块)应用

目录 一、前言 二、GPIO 2.1 GPIO简介 2.2 GPIO函数解析 2.3 LED驱动 2.4 KEY驱动 三、EXIT 3.1 EXIT简介 3.2 EXIT函数解析 3.3 EXIT驱动 四、LEDC 4.1 PWM原理解析 4.2 ESP32的LED PWM控制器介绍 4.3 LEDC函数解析 4.3.1 SW_PWM 4.3.2 HW_PWM 4.4 LEDC驱动 …

鸿蒙 ArkWeb 加载优化方案详解(2025 最佳实践)

适用平台&#xff1a;HarmonyOS NEXT / API 10 关键词&#xff1a;ArkWeb、WebviewController、NodeController、预加载、预连接、预渲染、性能优化一、前言&#xff1a;为什么必须优化 ArkWeb 加载&#xff1f;在鸿蒙生态中&#xff0c;ArkWeb 是系统级的 Web 容器引擎&#x…

JavaScript案例(乘法答题游戏)

项目概述 使用原生JavaScript实现一个乘法答题游戏&#xff0c;随机生成乘法题目&#xff0c;判断答案正误并记录分数&#xff0c;通过localStorage实现分数持久化存储。 核心功能需求 随机题目生成&#xff1a;动态生成1-10之间的乘法题答题交互&#xff1a;输入答案并提交…

EXCEL删除数据透视表

wps版 点击红框内任意区域 在顶部工具栏选择删除Excel 版 1.点击红框内任意区域2. 点击Enable Selection,再按住键盘上的Delete键&#xff0c;记住不是Backspace键

Python 飞机大战:从零开发经典 2D 射击游戏

引言&#xff1a;重温经典游戏开发 飞机大战作为经典的 2D 射击游戏&#xff0c;承载了许多人的童年回忆。使用 Python 和 Pygame 开发这样一款游戏不仅能重温经典&#xff0c;更是学习游戏开发绝佳的实践项目。本文将带你从零开始&#xff0c;一步步实现一个完整的飞机大战游…

Vue项目中实现浏览器串口通信:Web Serial API完整指南

前言 在现代Web开发中&#xff0c;随着IoT设备和硬件交互需求的增长&#xff0c;浏览器与串口设备的通信变得越来越重要。本文将详细介绍如何在Vue项目中使用Web Serial API实现串口通信功能&#xff0c;为开发者提供一个完整的解决方案。 技术背景 传统方案的局限性 传统的串口…

Github怎么只下载某个目录文件?(Git稀疏检出、GitZip for Github插件、在线工具DownGit)Github下载目录

文章目录**方法一&#xff1a;使用 Git 的稀疏检出&#xff08;Sparse Checkout&#xff09;**&#xff08;略&#xff09;**步骤&#xff1a;****方法二&#xff1a;使用 SVN 下载特定目录**&#xff08;略&#xff09;**步骤&#xff1a;****方法三&#xff1a;使用浏览器插件…

把“多视图融合、深度传感”组合在一起,今天分享3篇3D传感技术干货

关注gongzhonghao【计算机sci论文精选】3D传感技术起源于工业领域高精度测量需求&#xff0c;早期以激光三角测量、结构光等技术为主&#xff0c;主要服务于制造业的零部件检测与形变分析。随着消费电子智能化升级&#xff0c;苹果iPhone X的Face ID将结构光技术推向大众市场&a…

dubbo源码之消费端启动的高性能优化方案

一、序言 dubbo作为一款最流行的服务治理框架之一,在底层做了很多的优化,比如消费端在启动的时候做了很多性能提升的设计,接下来从连接的层面、序列化功能的层面进行介绍下。 二、优化点 1、消费端在服务启动的时候会调用DubboProtocol类的protocolBindingRefer方法来创建…

zookeeper常见命令和常见应用

前言 ZooKeeper自带一个交互式命令行工具&#xff08;通过zkCli.sh或zkCli.cmd启动&#xff09;&#xff0c;提供了一系列操作ZooKeeper数据节点的命令 下面我们对zookeeper常用命令进行介绍 使用prettyZoo命令行窗口 使用prettyZoo客户端链接zookeeper 打开zookeeper命令…

前端异步任务处理总结

一、异步任务常见场景网络请求&#xff1a;fetch()、axios 等 API 调用定时操作&#xff1a;setTimeout、setInterval用户交互&#xff1a;事件监听回调资源加载&#xff1a;图片/脚本动态加载Web Workers&#xff1a;后台线程计算二、核心处理方案1. Promise&#xff08;ES6&a…

机器学习第三课之逻辑回归(二)LogisticRegression

目录 简介 一.分类评估⽅法 1.混淆矩阵 2.精确率(Precision)与召回率(Recall) 3.F1-score 4.分类评估报告api 2.正则化惩罚 3.⽋拟合和过拟合 4.K折交叉验证 5.代码分析 简介 接上一篇博客最后 机器学习第二课之逻辑回归&#xff08;一&#xff09;LogisticRegres…

基于ELK Stack的实时日志分析与智能告警实践指南

基于ELK Stack的实时日志分析与智能告警实践指南 一、业务场景描述 在生产环境中&#xff0c;服务实例数量众多&#xff0c;日志量激增&#xff0c;传统的文本 grep 或 SSH 登录方式已无法满足实时监控与故障定位需求。我们需要搭建一个可扩展、低延迟的日志收集与分析平台&…

需求变更过程中出现的团队资源冲突问题处理的一些小技巧

​​一、资源冲突的典型场景​​ ​​技术资源争夺​​:多个需求同时需要同一开发人员或技术专家支持 ​​人力资源过载​​:突发需求导致团队成员工作量超负荷(如同时处理3个紧急需求) ​​设备/环境冲突​​:测试服务器资源不足或特定开发工具许可证被占用 ​​跨团队协…

基于Matlab图像处理的液晶显示器表面缺陷检测与分类研究

本课题设计并实现了一种基于 MATLAB 的图像缺陷检测系统&#xff0c;系统集成中值滤波、对比度增强、梯度检测与区域分析等图像处理技术&#xff0c;能够对图像中的点状、线状和块状缺陷进行有效识别与分类。用户可通过图形用户界面&#xff08;GUI&#xff09;导入待测图像&am…

prometheus应用demo(一)接口监控

目录 完整代码&#xff08;纯Cursor生成&#xff09; 1、pom 2、配置和启动类 3、自定义指标bean 4、上报 5、业务代码 一、统计API请求&#xff08;次数、响应码等&#xff09; 1、统计总数 关键代码&#xff1a; &#xff08;1&#xff09;自定义指标DTO &#xff0…

逃离智能家居“孤岛”!用 Home Assistant 打造你的全屋互联自由王国

文章目录&#x1f914; 痛点暴击&#xff1a;智能家居的“巴别塔困境”&#x1f6e0;️ Home Assistant 是个啥&#xff1f;简单粗暴版定义&#x1f50d; 硬核拆解&#xff1a;Home Assistant 的魅力之源&#x1f680; 上车指南&#xff1a;如何开始你的 HA 之旅&#xff1f;第…

数据结构:如何判断一个链表中是否存在环(Check for LOOP in Linked List)

目录 初始思考&#xff1a;什么叫“链表有环”&#xff1f; ❌ 第一种直接想法&#xff08;失败&#xff09;&#xff1a;我们是不是能“记住走过的节点”&#xff1f; 那我们换一个思路&#xff1a;我们能否只用两个指针来检测环&#xff1f; 第一步&#xff1a;定义两个指…