在Spring Boot项目中使用Zookeeper和Curator实现高效、可靠的分布式锁

news/2025/1/10 15:34:27/

要在 Spring Boot 项目中使用 Zookeeper 和 Curator 实现高效、可靠的分布式锁,可以参考以下步骤和优化建议:

1. 引入依赖

pom.xml 中添加 Curator 和 Zookeeper 相关依赖:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>5.1.0</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>5.1.0</version></dependency><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.8.0</version></dependency>
</dependencies>

2. 配置 Zookeeper 连接

application.yml 中配置 Zookeeper 连接字符串:

zookeeper:connect-string: localhost:2181

3. 配置 Curator 客户端

创建一个配置类来初始化 Curator 客户端:

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryNTimes;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ZookeeperConfig {@Value("${zookeeper.connect-string}")private String connectString;@Bean(initMethod = "start", destroyMethod = "close")public CuratorFramework curatorFramework() {return CuratorFrameworkFactory.builder().connectString(connectString).sessionTimeoutMs(5000).retryPolicy(new RetryNTimes(3, 5000)).build();}
}

4. 实现分布式锁服务

创建一个服务类来封装分布式锁的获取和释放逻辑,并进行一些优化:

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;@Service
public class DistributedLockService {private static final Logger logger = LoggerFactory.getLogger(DistributedLockService.class);@Autowiredprivate CuratorFramework curatorFramework;// 重试获取锁的次数private static final int MAX_RETRIES = 3;// 每次重试的间隔时间private static final int RETRY_INTERVAL_MS = 1000;// 获取分布式public boolean acquireLock(String lockPath, int timeout, TimeUnit timeUnit) {InterProcessMutex lock = new InterProcessMutex(curatorFramework, lockPath);for (int i = 0; i < MAX_RETRIES; i++) {try {if (lock.acquire(timeout, timeUnit)) {logger.info("成功获取分布式锁,锁路径: {}", lockPath);return true;}} catch (Exception e) {logger.error("获取分布式锁失败,尝试重试,锁路径: {}", lockPath, e);}try {TimeUnit.MILLISECONDS.sleep(RETRY_INTERVAL_MS);} catch (InterruptedException e) {logger.error("重试间隔被中断", e);Thread.currentThread().interrupt();}}logger.warn("经过多次重试仍无法获取分布式锁,锁路径: {}", lockPath);return false;}// 释放分布式public void releaseLock(String lockPath) {InterProcessMutex lock = new InterProcessMutex(curatorFramework, lockPath);try {lock.release();logger.info("成功释放分布式锁,锁路径: {}", lockPath);} catch (Exception e) {logger.error("释放分布式锁失败,锁路径: {}", lockPath, e);}}
}

5. 使用分布式

在需要使用分布式锁的地方注入 DistributedLockService 并调用相应方法:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DistributedLockUsageController {@Autowiredprivate DistributedLockService distributedLockService;@GetMapping("/protected-operation")public String protectedOperation(@RequestParam String lockPath) {int timeout = 10;TimeUnit timeUnit = TimeUnit.SECONDS;if (distributedLockService.acquireLock(lockPath, timeout, timeUnit)) {try {// 这里放置需要同步执行的业务逻辑return "成功获取锁并执行了受保护的操作";} finally {distributedLockService.releaseLock(lockPath);}} else {return "无法获取锁,操作被拒绝";}}
}

优化建议

  • 重试机制:在获取锁时增加重试机制,如上述代码中的 MAX_RETRIESRETRY_INTERVAL_MS,以提高获取锁的成功率。
  • 异常处理:在获取和释放锁的过程中,对可能出现的异常进行详细的日志记录,便于排查问题。
  • 锁粒度:根据业务需求合理设置锁的粒度,避免锁的范围过大影响系统性能。
  • 锁超时:设置合理的锁超时时间,防止因锁长时间未释放而导致的死锁问题。

通过以上步骤和优化建议,可以在 Spring Boot 项目中实现高效、可靠的分布式锁。


http://www.ppmy.cn/news/1562008.html

相关文章

开关不一定是开关灯用 - 命令模式(Command Pattern)

命令模式&#xff08;Command Pattern&#xff09; 命令模式&#xff08;Command Pattern&#xff09;命令设计模式命令设计模式结构图命令设计模式涉及的角色 talk is cheap&#xff0c; show you my code总结 命令模式&#xff08;Command Pattern&#xff09; 命令模式&…

maven下载依赖报错:on-resolvable parent POM xxx

maven 构建项目时报错 Non-resolvable parent POM for com.itheima:integation-mybatis:0.0.1-SNAPSHOT: org.springframework.boot:spring-boot-starter-parent:pom:2.5.3 failed to transfer from http://maven.aliyun.com/nexus/content/groups/public/ during a previous a…

[备忘.OFD]OFD是什么、OFD与PDF格式文件的互转换

‌OFD&#xff08;Open Fixed-layout Document&#xff09;是一种由工业和信息化部软件司牵头中国电子技术标准化研究院制定的版式文档国家标准&#xff0c;属于中国的一种自主格式‌‌。OFD旨在打破政府部门和党委机关电子公文格式不统一的问题&#xff0c;以方便电子文档的存…

AIDD-人工智能药物设计-通过组合生物合成产生新的类似物的抗真菌费尔南型三萜多聚类素的生物合成表征

Org. Biomol. Chem.|通过组合生物合成产生新的类似物的抗真菌费尔南型三萜多聚类素的生物合成表征 今天为大家介绍的是来自Xin-Yu Li、Jian-Ming Lv和Zhi-Qin Cao团队的一篇论文。费尔南型三萜是植物和真菌中的一类具有广泛生物活性的天然产物&#xff0c;其中真菌来源的Polyt…

深度学习与计算机视觉 (博士)

文章目录 零、计算机视觉概述一、深度学习相关概念1.学习率η2.batchsize和epoch3.端到端(End-to-End)、序列到序列(Seq-to-Seq)4.消融实验5.学习方式6.监督学习的方式(1)有监督学习(2)强监督学习(3)弱监督学习(4)半监督学习(5)自监督学习(6)无监督学习(7)总结&#xff1a;不同…

运动相机拍摄的视频打不开怎么办

3-10 GoPro和大疆DJI运动相机的特点&#xff0c;小巧、高清、续航长、拍摄稳定&#xff0c;很多人会在一些重要场合用来拍摄视频&#xff0c;比如可以用来拿在手里拍摄快速运动中的人等等。 但是毕竟是电子产品&#xff0c;有时候是会出点问题的&#xff0c;比如意外断电、摔重…

AF3 tensor_tree_map函数解读

AlphaFold3 递归函数 dict_map 和 tree_map&#xff0c;用于对嵌套的数据结构&#xff08;如字典、列表、元组等&#xff09;中的每个“叶子节点”应用指定的操作。最后&#xff0c;通过 partial 函数创建了 tensor_tree_map&#xff0c;专门用于对包含 torch.Tensor 的树形结构…

使用 Flask 和 PaddleOCR 的车牌识别项目安装与打包教程

文章目录 一、环境安装1. 安装 Python2. 创建虚拟环境3. 安装依赖 二、项目实现代码文件 app.py 三、打包流程1. 安装 pyinstaller2. 生成可执行文件3. 验证可执行文件 四、测试车牌识别服务1. 使用 Postman 或 curl 测试2. 校验车牌 五、提供给运维的打包文件 本教程基于 Flas…