深入探讨在SpringBoot中分布式锁的实现与应用

当在Spring Boot 中使用分布式锁时,你可以借助各种库和技术来实现。其中,Redis 和 ZooKeeper 是两个常用的分布式锁实现工具。下面将展示如何在 Spring Boot 中使用这两种工具实现分布式锁。

Redis 分布式锁

优点:
简单易用: Redis 的分布式锁使用简单,通过 Redis 的 setnx 和 expire 命令可以轻松实现。
性能较好: Redis 是内存型数据库,读写速度快,适合高并发的场景。
丰富的数据结构: Redis 提供了丰富的数据结构和操作,可以方便地扩展锁的功能,比如设置超时时间、自动续期等。

缺点:
单点故障: Redis 是一个单点服务,如果 Redis 服务出现故障,可能会导致整个系统的锁失效。
数据一致性: Redis 采用主从复制机制,可能存在数据同步延迟,不适合对数据一致性要求极高的场景。

使用 Redis 实现分布式锁
添加 Redis 依赖
确保在 pom.xml 文件中添加 Redis 依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

编写 Redis 分布式锁的工具类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;@Component
public class RedisDistributedLock {@Autowiredprivate StringRedisTemplate redisTemplate;public boolean acquireLock(String lockKey, String value, long expireTime) {return redisTemplate.opsForValue().setIfAbsent(lockKey, value, expireTime, TimeUnit.MILLISECONDS);}public void releaseLock(String lockKey, String value) {String currentValue = redisTemplate.opsForValue().get(lockKey);if (currentValue != null && currentValue.equals(value)) {redisTemplate.delete(lockKey);}}
}

在业务代码中使用 Redis 分布式锁

@Autowired
private RedisDistributedLock redisDistributedLock;public void someMethod() {String lockKey = "resource-lock";String value = "unique-value"; // 可以是唯一的标识符try {boolean isLocked = redisDistributedLock.acquireLock(lockKey, value, 5000); // 锁定5秒钟if (isLocked) {// 执行需要加锁的业务逻辑// ...} else {// 获取锁失败的处理逻辑// ...}} finally {redisDistributedLock.releaseLock(lockKey, value);}
}

ZooKeeper 分布式锁

优点:
高可用性: ZooKeeper 是一个高可用的分布式协调服务,能够保证服务的可用性。
严格的一致性: ZooKeeper 保证了严格的数据一致性,适合对数据一致性要求高的场景。
顺序性: ZooKeeper 提供了顺序节点特性,可以实现公平锁。

缺点:
复杂性: ZooKeeper 的使用较为复杂,需要了解其 API 和一致性模型,对开发者的要求较高。
性能较差: 相比 Redis,ZooKeeper 的性能较差,适合数据量小、对一致性要求高的场景。

使用 ZooKeeper 实现分布式锁
添加 ZooKeeper 依赖

<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>${zookeeper.version}</version>
</dependency>
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>${curator.version}</version>
</dependency>

编写 ZooKeeper 分布式锁的工具类

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;@Component
public class ZooKeeperDistributedLock {@Autowiredprivate CuratorFramework curatorFramework;public boolean acquireLock(String lockPath, long timeout, TimeUnit timeUnit) throws Exception {InterProcessMutex lock = new InterProcessMutex(curatorFramework, lockPath);return lock.acquire(timeout, timeUnit);}public void releaseLock(InterProcessMutex lock) throws Exception {if (lock != null && lock.isAcquiredInThisProcess()) {lock.release();}}
}

在业务代码中使用 ZooKeeper 分布式锁

@Autowired
private ZooKeeperDistributedLock zooKeeperDistributedLock;public void someMethod() {String lockPath = "/locks/resource-lock";InterProcessMutex lock = new InterProcessMutex(zookeeperClient, lockPath);try {boolean isLocked = zooKeeperDistributedLock.acquireLock(lock, 5, TimeUnit.SECONDS); // 锁定5秒钟if (isLocked) {// 执行需要加锁的业务逻辑// ...} else {// 获取锁失败的处理逻辑// ...}} catch (Exception e) {// 处理异常} finally {try {zooKeeperDistributedLock.releaseLock(lock);} catch (Exception e) {// 处理释放锁时的异常}}
}

如何选择

1. 并发性能需求: 如果对并发性能要求较高,且数据一致性要求不是非常严格,Redis 可能是更好的选择。
2. 数据一致性需求: 如果应用对数据一致性要求很高,对于分布式锁的正确性和可靠性有极高的要求,那么 ZooKeeper 可能更适合。
3. 简易性和成本: 如果在系统中已经使用了 Redis,并且没有对数据一致性有极高要求,那么利用 Redis 实现分布式锁可能更为简单和成本更低。

综上所述,选择 Redis 还是 ZooKeeper 实现分布式锁取决于你的具体场景需求。如果你更看重性能和简易性,Redis 是一个不错的选择;而如果你更关注数据一致性和可靠性,ZooKeeper 则更适合你的需求。在实际应用中,也可以根据具体情况结合两者的优势来实现分布式锁,比如利用 Redis 实现分布式锁的快速性和利用 ZooKeeper 来保证一致性。

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

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

相关文章

绝地求生:大逃杀,鼠标灵敏度设置教程及枪法练习技巧 鼠标灵敏度怎么设置

《绝地求生大逃杀》鼠标灵敏度怎么设置&#xff1f;作为一款FPS游戏&#xff0c;如何调整鼠标参数是大家急需掌握的&#xff0c;今天闲游盒带来“院长尼克”分享的《绝地求生大逃杀》鼠标灵敏度设置教程及枪法练习技巧&#xff0c;废话不多说&#xff0c;下面我们一起来看吧。 …

C语言——小细节和小知识7

一、逆序字符串 1、递归1 #include <stdio.h> #include <string.h>void ReverseArray(char *str) {char temp *str;//1int len (int)strlen(str);*str *(str len - 1);//2*(str len - 1) \0;//3if(strlen(str 1) > 2)//只要字符串还大于2&#xff0c;就…

【nodejs】Express概念与使用介绍

Express Express是基于Node.js平台&#xff0c;从内置模块http封装出来的第三方模块&#xff0c;可以更方便的开发Web服务器。 中文官网&#xff1a; http://www.expressjs.com.cn/ 一、基本使用 // 导入express const express require(express) // 创建web服务器 const a…

SpringBoot 2 集成Spark 3

前提条件: 运行环境&#xff1a;Hadoop 3.* Spark 3.* ,如果还未安装相关环境&#xff0c;请参考&#xff1a; Spark 初始 CentOS 7 安装Hadoop 3 单机版 SpringBoot 2 集成Spark 3 pom.xml <?xml version"1.0" encoding"UTF-8"?> <pro…

JavaScript基础练习题(五)

生成一个范围内的随机整数&#xff1a;编写一个函数&#xff0c;接收两个参数&#xff0c;表示范围的最小值和最大值&#xff0c;然后生成一个在这个范围内的随机整数。 生成指定长度的随机字符串&#xff1a;编写一个函数&#xff0c;接收一个参数表示字符串的长度&#xff0…

【数据结构和算法】---二叉树(2)--堆的实现和应用

目录 一、堆的概念及结构二、堆结构的实现2.1堆向下调整算法2.2堆向上调整算法2.3删除堆顶元素2.4插入元素2.5其他函数接口 三、堆结构的应用3.1堆排序3.2Top-k问题 四、堆概念及结构相关题目 一、堆的概念及结构 如果有一个数字集合&#xff0c;并把它的所有元素按完全二叉树…

MS6459字符叠加可兼容MAX7456

MS6459 是 OSD 电路,与 MCU 配合使用,可控制不同类型的显示系统。显示点阵为 1218&#xff0c;内置部分数字、英文字符、拉丁字符和中文字符。电路集成有上电复位电路和 VRAM 清零电路用于减轻 MCU 的工作量。 主要特点 输入信号&#xff1a;混合视频信号&#xff1b; 显示字符…

ksuser.dll文件缺失怎么办?软件或游戏无法启动,一键自动修复

很多小伙伴反馈&#xff0c;自己的电脑中了病毒&#xff0c;被杀毒软件清理后&#xff0c;在打开游戏或软件的时候&#xff0c;经常会报错“提示无法找到ksuser.dll文件&#xff0c;建议重新安装软件或游戏”。自己根据提示重装后&#xff0c;还是报错&#xff0c;不知道应该怎…

C++ Qt开发:SqlRelationalTable关联表组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍SqlRelationalTable关联表组件的常用方法及灵…

企业微信会话存档sdk报错:A fatal error has been detected by the Java Runtime Environment

错误信息 # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc0x00007f218f93485d, pid10, tid58 # # JRE version: OpenJDK Runtime Environment 18.9 (11.0.14.11) (build 11.0.14.11) # Java VM: OpenJDK 64-Bit Server VM 18.9…

【C语言】程序练习(四)

大家好&#xff0c;这里是争做图书馆扫地僧的小白。非常感谢各位的支持&#xff0c;也期待着您的关注。 目前博主有着C语言、C、linux以及数据结构的专栏&#xff0c;内容正在逐步的更新。 希望对各位朋友有所帮助同时也期望可以得到各位的支持&#xff0c;有任何问题欢迎私信与…

智能分析网关V4+太阳能供电模式,搭建鱼塘养殖远程视频监控方案

一、行业背景 传统的鱼塘养殖模式由于养殖区域面积大、管理难度高&#xff0c;经常会出现偷钓者、盗窃鱼苗、非法入侵等监管难题&#xff0c;给养殖户带来了不小的经济损失。为了解决这些问题&#xff0c;搭建鱼塘远程监控系统成为了必要之举。通过远程监控系统&#xff0c;管…

跨域问题实战及分析

自己写了一个nodejs服务器&#xff0c;在html页面中调用接口&#xff0c;遇到了跨域问题,该怎么解决呢&#xff1f; server.js 创建服务器 const expressrequire(express); const appexpress();//创建express服务器 app.listen(80,()>{//启动服务器console.log(express se…

别一言不合就重装系统!Windows 无法正常启动先试试这些办法

你是否遇到过在升级或安装 Windows 10 操作系统&#xff0c;Windows 无法正常启动进入桌面&#xff0c;甚至陷入无限循环。造成的原因有很多&#xff0c;比如 Windows 更新&#xff0c;安装了新的软件或者驱动程序&#xff0c;系统文件损坏等等。那遇见 Windows 启动不了怎么办…

【Midjourney】Midjourney根据prompt提示词生成人物图片

目录 &#x1f347;&#x1f347;Midjourney是什么&#xff1f; &#x1f349;&#x1f349;Midjourney怎么用&#xff1f; &#x1f514;&#x1f514;Midjourney提示词格式 Midjourney生成任务示例 例1——航空客舱与乘客 prompt prompt翻译 生成效果 大图展示 细节大…

Unity 设置 Text 颜色 #FF7B2A

在Unity中&#xff0c;你可以使用 Color32 或 ColorUtility.TryParseHtmlString 来设置带有HTML颜色代码的文本颜色。以下是两种方法的示例&#xff1a; 使用 Color32&#xff1a; using UnityEngine; using UnityEngine.UI;public class SetTextColor : MonoBehaviour {publi…

铂炭催化剂,2026年市场预计将以6.5%左右的复合年增长率增长

铂碳催化剂广泛用于各种工业应用&#xff0c;包括化学、制药和汽车领域。在对清洁能源的需求不断增加和环境问题意识不断提高的推动下&#xff0c;铂碳催化剂市场正在稳步增长。本次分析&#xff0c;我们将从全球市场和中国市场分别考察铂碳催化剂市场的发展趋势。 全球市场分析…

Node.js笔记分享

Node.js 一、初识Node.js 与浏览器为Js提供前端运行环境相对应&#xff0c;Node.js是基于V8引擎的Js运行环境&#xff0c;为Js做后端开发提供了可能。 Node.js的作用 基于Express框架(http://www.expressjs.com.cn/)&#xff0c;可以快速构建Web 应用 基于Electron框架(ht…

【并发编程篇】线程安全问题_—_ConcurrentHashMap

文章目录 &#x1f354;情景引入&#x1f339;报错了&#xff0c;解决方案 &#x1f354;情景引入 我们运行下面的代码 package org.example.unsafe;import java.util.HashMap; import java.util.Map; import java.util.UUID;public class MapTest {public static void main(…

Kerberos安装教程与命令详解(超详细)

文章目录 前言一、安装准备1. 搭建集群2. 软件包介绍 二、使用shell脚本一键安装1. 复制脚本2. 增加执行权限3. 执行脚本 三、kdb5_util命令1. 简介2. 可用选项和命令的解释3. 常见命令及其说明4. 示例用法 四、kadmin命令1. 简介2. 可用选项和命令的解释3. 常见命令及其说明4.…