分布式锁实现(数据库+Redis+Zookeeper)
1. 数据库分布式锁
实现原理
-
基于唯一索引:
-
创建一张锁表,通过唯一索引(如锁名称)保证互斥性。
-
加锁:插入一条记录,成功则获取锁,失败则重试。
-
解锁:删除对应记录。
-
-
乐观锁(版本号):
-
使用版本号字段,更新时检查版本号是否匹配。
-
-
悲观锁(SELECT FOR UPDATE):
-
通过数据库行锁锁定记录(如
SELECT ... FOR UPDATE
)。
-
// 基于唯一索引的简单实现(JDBC示例)
public class DatabaseLock {
private Connection connection;
public boolean tryLock(String lockKey, String clientId, int expireSeconds) {
try {
String sql = "INSERT INTO distributed_lock (lock_key, client_id, expire_time) VALUES (?, ?, ?)";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, lockKey);
stmt.setString(2, clientId);
stmt.setTimestamp(3, new Timestamp(System.currentTimeMillis() + expireSeconds * 1000));
return stmt.executeUpdate() > 0;
} catch (SQLException e) {
return false;
}
}
public void unlock(String lockKey, String clientId) {
try {
String sql = "DELETE FROM distributed_lock WHERE lock_key = ? AND client_id = ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, lockKey);
stmt.setString(2, clientId);
stmt.executeUpdate();
} catch (SQLException ignored) {}
}
}
优缺点
-
优点:
-
实现简单,无需额外依赖。
-
-
缺点:
-
性能低(依赖数据库IO)。
-
无自动超时机制(需手动清理过期锁)。
-
单点故障风险。
-
适用场景
-
低频并发场景,或作为临时方案。
2. Redis分布式锁
实现原理
-
单节点锁(SETNX + EXPIRE):
-
加锁:使用
SET key value NX EX seconds
原子命令设置锁并指定超时时间。 -
解锁:通过 Lua 脚本校验客户端唯一标识后删除锁。
-
-
RedLock算法(多节点容错):
-
向多个独立 Redis 节点请求锁,半数以上成功视为加锁成功。
-
Java代码示例(Jedis客户端)
public class RedisLock {
private Jedis jedis;
private String lockKey;
private String clientId;
private int expireTime;
public RedisLock(Jedis jedis, String lockKey, int expireTime) {
this.jedis = jedis;
this.lockKey = lockKey;
this.clientId = UUID.randomUUID().toString();
this.expireTime = expireTime;
}
public boolean tryLock() {
// 加锁:SET lockKey clientId NX EX expireTime
String result = jedis.set(lockKey, clientId, SetParams.setParams().nx().ex(expireTime));
return "OK".equals(result);
}
public void unlock() {
// 解锁:通过Lua脚本保证原子性
String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
jedis.eval(luaScript, Collections.singletonList(lockKey), Collections.singletonList(clientId));
}
}
优缺点
-
优点:
-
高性能(基于内存操作)。
-
支持自动超时,避免死锁。
-
-
缺点:
-
时钟漂移可能导致锁提前释放。
-
RedLock 算法实现复杂,依赖多节点。
-
适用场景
-
高并发场景(如秒杀、限流)。
3. ZooKeeper分布式锁
实现原理
-
临时顺序节点:
-
加锁:客户端在 ZooKeeper 的锁目录下创建临时顺序节点。
-
监听机制:判断当前节点是否为最小节点,是则获取锁;否则监听前一个节点的删除事件。
-
-
临时节点:
-
创建临时节点,成功则获取锁,否则监听节点删除。
-
public class ZkLock {
private CuratorFramework client;
private String lockPath;
private InterProcessMutex lock;
public ZkLock(CuratorFramework client, String lockPath) {
this.client = client;
this.lockPath = lockPath;
this.lock = new InterProcessMutex(client, lockPath);
}
public boolean tryLock(long timeout, TimeUnit unit) {
try {
return lock.acquire(timeout, unit);
} catch (Exception e) {
return false;
}
}
public void unlock() {
try {
lock.release();
} catch (Exception ignored) {}
}
}
// 使用示例
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", new RetryNTimes(3, 1000));
client.start();
ZkLock zkLock = new ZkLock(client, "/locks/resource");
try {
if (zkLock.tryLock(10, TimeUnit.SECONDS)) {
// 执行业务逻辑
}
} finally {
zkLock.unlock();
}
优缺点
-
优点:
-
强一致性(ZooKeeper 的 ZAB 协议)。
-
自动释放锁(临时节点断开即删除)。
-
支持公平锁(顺序节点)。
-
-
缺点:
-
性能低于 Redis(频繁的节点操作和监听)。
-
需维护 ZooKeeper 集群。
-
适用场景
-
需要强一致性和高可靠性的场景(如金融交易)。
对比总结
特性 | 数据库锁 | Redis锁 | ZooKeeper锁 |
---|---|---|---|
实现复杂度 | 简单 | 中等 | 复杂 |
性能 | 低 | 高 | 中 |
可靠性 | 低 | 中(依赖集群) | 高 |
自动超时 | 手动实现 | 支持 | 支持(临时节点) |
公平性 | 不支持 | 不支持 | 支持 |
适用场景 | 低频简单场景 | 高并发场景 | 强一致性场景 |
选择建议
-
Redis分布式锁:优先用于高并发场景(如秒杀),需注意锁续期问题。
-
ZooKeeper分布式锁:用于需要强一致性和公平性的场景(如分布式事务)。
-
数据库锁:仅作为简单场景的临时方案。
注意事项
-
锁超时时间:根据业务操作合理设置,避免锁过早释放。
-
唯一客户端标识:防止其他客户端误删锁。
-
容错机制:Redis 建议使用 RedLock,ZooKeeper 需集群部署。
相关文章:
分布式锁实现(数据库+Redis+Zookeeper)
1. 数据库分布式锁 实现原理 基于唯一索引: 创建一张锁表,通过唯一索引(如锁名称)保证互斥性。 加锁:插入一条记录,成功则获取锁,失败则重试。 解锁:删除对应记录。 乐观锁&…...
七、Spring Boot:初识与项目搭建
深入解析 Spring Boot:初识与项目搭建 Spring Boot 是基于 Spring Framework 的开源 Java 基础框架,旨在简化 Spring 应用的开发过程。它通过“约定优于配置”的理念,极大地减少了开发中的配置工作,同时提供了“开箱即用”的功能…...
记录一下用docker克隆某授权制定ip的环境恢复
#首先还是要看日志根据问题去进行调整 java web的老项目配置文件一般是 bin启动里边的脚本 还有conf中的 xml配置文件 再或者就是classes中的配置文件,再或者就是lib中的jar包中的配置文件 1.安装docker 2.创建docker网络 docker network create --driver bridge --subnet…...
【含文档+PPT+源码】基于微信小程序的健康饮食食谱推荐平台的设计与实现
项目介绍 本课程演示的是一款基于微信小程序的健康饮食食谱推荐平台的设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本…...
主流虚拟化技术讲解
目录 VMware vSphere Microsoft Hyper-V KVM(Kernel-based Virtual Machine) OpenStack VMware vSphere 架构与组件:VMware vSphere 是基于裸金属虚拟化技术的平台,核心组件包括 ESXi 主机和 vCenter Server。ESXi 是虚拟化层…...
java开发——为什么要使用动态代理?
举个例子:假如有一个杀手专杀男的,不杀女的。代码如下: public interface Killer {void kill(String name, String sex);void watch(String name); }public class ManKiller implements Killer {Overridepublic void kill(String name, Stri…...
kotlin 知识点一 变量和函数
在Kotlin中定义变量的方式和Java 区别很大,在Java 中如果想要定义一个变 量,需要在变量前面声明这个变量的类型,比如说int a表示a是一个整型变量,String b表 示b是一个字符串变量。而Kotlin中定义一个变量,只允许在变量…...
将CUBE或3DL LUT转换为PNG图像
概述 在大部分情况下,LUT 文件通常为 CUBE 或 3DL 格式。但是我们在 OpenGL Shader 中使用的LUT,通常是图像格式的 LUT 文件。下面,我将教大家如何将这些文件转换为 PNG 图像格式。 条形LUT在线转换(不是8x8网络)&am…...
侯捷 C++ 课程学习笔记:类的声明与构造函数
目录 一、类的声明 二、内联函数 三、访问级别 四、构造函数 五、构造函数重载 六、实际应用案例 七、学习心得 一、类的声明 类的声明是定义类的基本结构,包括类的成员变量和成员函数。类的声明分为类头和类体两部分。 类头(class head…...
BGP状态和机制
BGP邻居优化 为了增加稳定性,通常建议实验回环口来建立邻居。更新源:建立邻居和邻居所学习到的路由的下一跳。多跳:EBGP邻居建立默认选哟直连,因为TTL=1,如果非直连,必须修改TTL。命令备注peer 2.2.2.2 connect-interface lo1配置更新源peer 2.2.2.2 ebgp-max-hop 2配置T…...
MongoDB 数据库简介
MongoDB 数据库简介 引言 随着互联网技术的飞速发展,数据已经成为企业的重要资产。为了高效地管理和处理这些数据,数据库技术应运而生。MongoDB作为一种流行的NoSQL数据库,因其灵活的数据模型和高效的数据处理能力,受到了广泛的关注。本文将为您详细介绍MongoDB的基本概念…...
浏览器下载vue.js.devtools,谷歌浏览器和edg浏览器
1、谷歌浏览器下载: 情况一:如果谷歌应用商店可以打开,那么就直接到谷歌应用商店下载,直接搜索vue.js.devtools添加扩展即可。 情况二:谷歌浏览器的谷歌应用商城打不开,那么就百度搜索极简插件找到vue.js.…...
Android AOSP系统裁记录
Android 系统裁剪是指根据需求移除不必要的组件和功能,以优化系统性能、减少存储占用或满足特定设备需求。以下是 Android 系统裁剪的基本步骤: 1. 准备环境 操作系统:推荐使用 Ubuntu 或 macOS。 工具: Android SDK Android N…...
Could not download npm for node v14.21.3(nvm无法下载节点v14.21.3的npm)
场景描述:之前的项目用的是node以前的版本,使用nvm没下载下来,npm命令执行不了 错误如下图,15版本的node同理,下载的都是.exe可执行文件的扩展名,使用npm命令终端无法识别 解决思路:去node官网…...
React进阶之React核心源码解析(三)
React核心源码解析 diff多节点比较diff两轮遍历比较第一轮比较第二轮比较Update 状态更新Concurrent Modediff 多节点比较diff isArray方法比较 节点更新// 更新前 <ul><li key="0" className="before">0<li><li key=...
2025吐槽季第一弹---腾讯云EO边缘安全加速平台服务
前言: 关于EO边缘安全加速平台服务 参照:产品概述,具体如下: 边缘安全加速平台 EO(Tencent Cloud EdgeOne,下文简称为 EdgeOne)是国内首款基于全新架构的真正一体化的边缘安全加速平台。提供全面的安全防…...
Dify自定义工作流集成指南:对接阿里云百炼文生图API的实现方案
dify工作流的应用基本解释 dify应用发布相关地址:应用发布 | Dify 根据官方教程,我们可以看到dify自定义的工作流可以发布为----工具 这个教程将介绍如何通过工作流建立一个使用阿里云百炼文生图模型。 工具则可以给其他功能使用,如agent…...
WebSocket简单介绍 并接入deepseek
目录 什么是 WebSocket?工作原理: 为什么需要 WebSocket?WebSocket 的优势HTTP 和 WebSocket 的区别WebSocket 的劣势WebSocket 的应用场景WebSocket 握手过程1. 客户端发起握手请求2. 服务器响应握手请求3. 建立连接 WebSocket 事件处理WebS…...
android 新增native binder service 方式(三)
书接上回,继续第三种方式,是手动生成 service binder 的方法,项目结构 1,编译aidl aidl 文件保持不变,如何生成Bn和Bp 文件呢。 aidl -I ./libserviceaidl/aidl -h ./ -o ./ --langcpp libserviceaidl/aidl/com/test/IService.a…...
linux--多进程开发(5)--进程
进程间通讯概念 每两个进程之间都是独立的资源分配单元,不同进程之间不能直接访问另一个进程的资源。 但不同的进程需要进行信息的交互和状态的传递等,因此需要进程间通信(IPC,inter processes cimmunication) 进程通信的目的: …...
分享httprunner 结合django实现平台接口自动化方案
说明,可以直接在某个视图集定义自定义接口来验证。 调试1:前端界面直接编写yaml文件. 新增要实现存数据到mysql,同时存文件到testcase下, 如test.yaml 更新yaml数据,同时做到更新 testcase下的文件,如test.yaml acti…...
前端面试题之HTML篇
1.src和href的区别 src用于替换当前元素,href用于在当前文档和引用资源之间确立联系。 src可用于img、input、style、script、iframe---同步加载执行 href可用于link、a---异步 1.用途不同 src 用于引入外部资源,通常是图像、视频、JavaScript 文件等&am…...
Selenium 调用模型接口实现功能测试
要使用 Selenium 调用模型接口实现功能测试,可按以下步骤进行: 1. 环境准备 安装 Selenium:使用 pip install selenium 安装 Selenium 库。安装浏览器驱动:根据使用的浏览器(如 Chrome、Firefox 等)下载对应的驱动,并将其添加到系统的环境变量中。例如,Chrome 浏览器需…...
java后端开发day18--学生管理系统
(以下内容全部来自上述课程) 1.业务分析并搭建主菜单 1.需求 采取控制台的方式去书写学生管理系统 2.分析 1.初始菜单 2.学生类 属性:id,姓名,年龄,家庭住址 3.添加功能 键盘录入每一个学生信息并…...
计算机毕业设计SpringBoot+Vue.jst0图书馆管理系统(源码+LW文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
【DeepSeek】【GPT-Academic】:DeepSeek集成到GPT-Academic(官方+第三方)
目录 1 官方deepseek 1.1 拉取学术GPT项目 1.2 安装依赖 1.3 修改配置文件中的DEEPSEEK_API_KEY 2 第三方API 2.1 修改DEEPSEEK_API_KEY 2.2 修改CUSTOM_API_KEY_PATTERM 2.3 地址重定向 2.4 修改模型参数 2.5 成功调用 2.6 尝试添加一个deepseek-r1参数 3 使用千帆…...
生成对抗网络(GAN):让机器学习“创造”新世界
目录 引言 什么是生成对抗网络(GAN)? GAN的核心原理 GAN的损失函数 GAN的变种 1. 条件生成对抗网络(Conditional GAN, cGAN) 2. 深度卷积生成对抗网络(DCGAN) 3. 生成对抗网络的 Wassers…...
JavaScript系列(87)--Webpack 高级配置详解
Webpack 高级配置详解 🛠️ Webpack 是前端工程化中最流行的构建工具之一,掌握其高级配置可以帮助我们构建更高效、更优化的应用。本文将深入探讨Webpack的高级配置技巧和最佳实践。 Webpack 核心概念回顾 🌟 💡 小知识…...
48.日常算法
1.面试题 03.06. 动物收容所 题目来源 动物收容所。有家动物收容所只收容狗与猫,且严格遵守“先进先出”的原则。在收养该收容所的动物时,收养人只能收养所有动物中“最老”(由其进入收容所的时间长短而定)的动物,或…...
MySql数据库运维学习笔记
数据库运维常识 DQL、DML、DCL 和 DDL 是 SQL(结构化查询语言)中的四个重要类别,它们分别用于不同类型的数据库操作,下面为你简单明了地解释这四类语句: 1. DQL(数据查询语言,Data Query Langu…...
Starlink卫星动力学系统仿真建模第十讲-基于SMC和四元数的卫星姿态控制示例及Python实现
基于四元数与滑模控制的卫星姿态控制 一、基本原理 1. 四元数姿态表示 四元数运动学方程: 3. 滑模控制设计 二、代码实现(Python) 1. 四元数运算工具 import numpy as npdef quat_mult(q1, q2):"""四元数乘法""…...
MongoDB学习
MongoDB 是一种流行的 NoSQL 数据库,以文档存储为核心,适用于高灵活性、高扩展性的场景。本文将从基础概念到实际应用,带你快速掌握 MongoDB 的核心操作。 1. MongoDB 简介 什么是 MongoDB? MongoDB 是一个基于分布式文件存储的…...
水利工程安全包括哪几个方面
水利工程安全培训的内容主要包括以下几个方面: 基础知识和技能培训 : 法律法规 :学习水利工程相关的安全生产法律法规,了解安全生产标准及规范。 事故案例 :通过分析事故案例,了解事故原因和教训&#x…...
九、数据治理架构流程
一、总体结构 《数据治理架构流程图》(Data Governance Architecture Flowchart) 水平结构:流程图采用水平组织,显示从数据源到数据应用的进程。 垂直结构:每个水平部分进一步划分为垂直列,代表数据治理的…...
Spring boot中的@ConfigurationProperties注解
Spring boot中的ConfigurationProperties注解 ConfigurationProperties 是 Spring Boot 提供的一个强大注解,用于将配置文件(如 application.properties 或 application.yml)中的配置绑定到一个 Java 对象中。它不仅简化了配置管理ÿ…...
04性能监控与调优篇(D2_JVM调优⼯具)
目录 学习前言 讲解一:理论篇(深入理解JVM第三版) 一、虚拟机性能监控、故障处理工具 1. 基本介绍 2. 基础故障处理工具 jps:虚拟机进程状况工具 jstat:虚拟机统计信息监视工具 jinfo:Java配置信息工…...
DeepSeek 提示词:基础结构
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…...
OkHttp、Retrofit、RxJava:一文讲清楚
一、okHttp的同步和异步请求 Call 是 OkHttp 的核心接口,代表一个已准备好执行的 HTTP 请求。它支持 同步 和 异步 两种模式: enqueue——>okHttp异步 OkHttpClient client new OkHttpClient();Request request new Request.Builder().url("…...
AI前端加速科学研究:ScriptEcho赋能科研新纪元
科学研究正面临前所未有的挑战。数据以前所未有的速度爆炸式增长,研究课题也变得日益复杂。如何高效地处理海量数据、构建复杂模型、并将其转化为有意义的结论,成为摆在科研人员面前的一道难题。传统的科研模式往往需要耗费大量的时间和精力在数据处理、…...
从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)?
本文首发:从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)? 阿里云百炼和火山引擎都推出了免费的 DeepSeek 模型体验额度,今天我和大家一起搭建一个本地的专属 AI 助手。 阿里云百炼为 …...
ChatGPT背后的理论基础:从预训练到微调的深度解析
友情提示:本文内容由银河易创(https://ai.eaigx.com)AI创作平台GPT-4o-mini模型生成,仅供参考。请根据具体情况和需求进行适当的调整和验证。 随着人工智能特别是自然语言处理技术的飞速发展,ChatGPT作为一种强大的对话…...
Java八股文(下)
Java八股文下篇 八、JVM高级篇1、JVM的内存模型以及分区介绍一下?2、四种引用方式有什么?3、判断是否为垃圾算法?4、垃圾回收算法介绍一下?5、类的生命周期以及类加载过程6、加载器种类有什么?7、什么是双亲委派模型以…...
软考高级【网络规划设计师】 综合知识
引言:软考高级【网络规划设计师】共分为3个部分,综合知识,案例分析,论文。这里主要讲诉综合知识的相关内容。综合知识一共75道单选,题目跟网工类似,稍难。 第1章 计算机网络基础 考点分析: 本…...
django框架使用
一、app注册: pycharm使用django框架,注意在注册界面时就创建app,如果没有创建app。就在终端中运行 python manage.py startapp [app名] 然后再在settings.py里注册。 格式为: [app名].apps.[首字母大写的app名]Config 二、创…...
Linux主机用户登陆安全配置
Linux主机用户登陆安全配置 在Linux主机上进行用户登录安全配置是一个重要的安全措施,可以防止未经授权的访问。以下是如何创建用户hbu、赋予其sudo权限,以及禁止root用户SSH登录,以及通过ssh key管理主机用户登陆。 创建用户hbu 使用具有…...
MySQL | MySQL库、表的基本操作
MySQL库、表的基本操作01 一、库操作1.1 查看数据库1.2 创建数据库1.3 选择数据库1.4 查看创建数据库的SQL语句1.5 修改数据库1.6 删除数据库 二、表操作2.1 创建数据表2.2 查看表2.3 查看表结构2.4 查看创建数据库的SQL语句2.5 修改表2.6 删除表 ⚠️MySQL版本 8.0 一、库操作…...
【Uniapp-Vue3】在uniapp中使用pinia的基本用法
引入pinia: 在main.js中对pinia进行引入,使用和导出 import * as Pinia from pinia; // 引入pinia app.use(Pinia.createPinia()); // 使用pinia 在项目根目录下创建一个stores文件夹,里面创建一个counter.js文件 我们在counter.js中定义…...
mysql中的计算日期函数 理解、用法
三种计算日期的函数 函数用途示例DATEDIFF()计算两个日期的天数差DATEDIFF(2023-10-05, 2023-10-01) → 4TIMESTAMPDIFF()按指定单位(年、月、小时等)计算差TIMESTAMPDIFF(MONTH, 2023-01-01, 2023-03-01) → 2DATE_ADD()日期加法DATE_ADD(2023-10-01, …...
HTTP实验(ENSP模拟器实现)
目录 HTTP概述 HTTP实验 HTTPS 实验 HTTP概述 HTTP(HyperText Transfer Protocol,超文本传输协议),设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。 HTTP定义了多种请求方法,常用的包括: …...
Ubuntu指令(一)
一、终端操作指令 打开终端,有两种便捷方式: 直接点击系统中的终端按钮;使用快捷键ctrl alt T。 关闭终端,同样有多种选择: 在终端输入exit指令;使用快捷键ctrl d;直接点击终端窗口的关闭…...