当前位置: 首页 > news >正文

【Redis】分布式锁

目录

  • 分布式锁
    • 分布式锁实现的关键
  • Redisson实现分布式锁
    • 看门狗机制

分布式锁

为什么要使用分布式锁,或者分布式锁的使用场景?

定时任务。在分布式场景下,只控制一台服务器执行定时任务,这就需要分布式锁

要控制定时任务在同一时间只有 1 个服务器能执行,方案有哪些?

  1. 分离定时任务程序和主程序,只在 1 个服务器运行定时任务。成本太大
  2. 写死配置。每个服务器都执行定时任务,但是只有 ip 符合配置的服务器才真实执行业务逻辑,其他的直接返回。成本最低;但是我们的 IP 可能是不固定的,会把 IP 写的太死了
  3. 动态配置,配置是可以轻松的、很方便地更新的(代码无需重启),但是只有 ip 符合配置的服务器才真实执行业务逻辑。问题:服务器多了、IP 不可控还是很麻烦,还是要人工修改
    • 配置写在数据库 、Redis、配置中心(Nacos、Apollo、Spring Cloud Config)
  4. 分布式锁,只有抢到锁的服务器才能执行业务逻辑。坏处:增加成本;好处:不用手动配置,多少个服务器都一样。

Java 实现锁:synchronized 关键字、并发包的类
问题:只对单个 JVM 有效

分布式锁实现的关键

抢锁机制

怎么保证同一时间只有 1 个服务器能抢到锁?

核心思想 就是:先来的人先把数据改成自己的标识(服务器 ip),后来的人发现标识已存在,就抢锁失败,继续等待。等先来的人执行方法结束,把标识清空,其他的人继续抢锁。

实现方式有:

  • MySQL 数据库:select for update 行级锁(最简单)
  • Redis 实现:内存数据库,读写速度快 。支持 setnxlua 脚本,比较方便我们实现分布式锁。

实现细节:

  1. 锁一定要加过期时间
  2. 用完锁要释放,释放的时候检查是否是自己的锁
  3. 如果方法执行时间过长,锁要能进行续约
  4. Redis 如果是集群(而不是只有一个 Redis),如果分布式锁的数据不同步怎么办? 使用红锁

Redisson实现分布式锁

Redisson 是一个 java 操作 Redis 的客户端,提供了大量的分布式数据集来简化对 Redis 的操作和使用,可以让开发者像使用本地集合一样使用 Redis,完全感知不到 Redis 的存在。

使用方式

  1. spring boot starter 引入(不推荐,版本迭代太快,容易冲突)链接
  2. 使用Redisson依赖 链接

RedissonConfig

/*** Redisson 配置*/
@Configuration
@ConfigurationProperties(prefix = "spring.redis")
@Data
public class RedissonConfig {private String host;private String port;@Beanpublic RedissonClient redissonClient() {// 1. 创建配置Config config = new Config();String redisAddress = String.format("redis://%s:%s", host, port);//  使用单个Redis,没有开集群 useClusterServers()  设置地址和使用库config.useSingleServer().setAddress(redisAddress).setDatabase(3);// 2. 创建实例RedissonClient redisson = Redisson.create(config);return redisson;}
}

Redisson测试


@SpringBootTest
public class RedissonTest {@Resourceprivate RedissonClient redissonClient;@Testvoid test() {// list,数据存在本地 JVM 内存中List<String> list = new ArrayList<>();list.add("yupi");System.out.println("list:" + list.get(0));list.remove(0);// 数据存在 redis 的内存中RList<String> rList = redissonClient.getList("test-list");rList.add("yupi");System.out.println("rlist:" + rList.get(0));rList.remove(0);// mapMap<String, Integer> map = new HashMap<>();map.put("yupi", 10);map.get("yupi");RMap<Object, Object> map1 = redissonClient.getMap("test-map");// set// stack}
}

看门狗机制

Redisson会开一个监听线程,如果锁的方法还没执行完,就帮你重置 redis 锁的过期时间。

原理:

  • 监听当前线程,默认过期时间是 30 秒,每 10 秒续期一次(补到 30 秒)
  • 如果线程挂掉(注意 debug 模式也会被它当成服务器宕机),则不会续期

相关文章:

【Redis】分布式锁

目录 分布式锁分布式锁实现的关键 Redisson实现分布式锁看门狗机制 分布式锁 为什么要使用分布式锁&#xff0c;或者分布式锁的使用场景&#xff1f; 定时任务。在分布式场景下&#xff0c;只控制一台服务器执行定时任务&#xff0c;这就需要分布式锁 要控制定时任务在同一时间…...

Linux访问firefox 显示Error: no DISPLAY environment variable specified

在 CentOS 7 中访问 Firefox 浏览器时&#xff0c;出现 "Error: no DISPLAY environment variable specified" 的错误提示通常是由于缺少显示环境变量导致的。 要解决这个问题&#xff0c;你可以按照以下步骤进行配置&#xff1a; 1. 确保已经安装 X Window Syst…...

线性回归简介

线性回归简介 1、情景描述2、线性回归 1、情景描述 假设&#xff0c;我们现在有这么一张图&#xff1a; 其中&#xff0c;横坐标x表示房子的面积&#xff0c;纵坐标y表示房价。我们猜想x与y之间存在线性关系&#xff1a; y k x b ykxb ykxb 现在&#xff0c;思考一个问题&…...

Log4net 教程

一、Log4net 教程 在CodeProject上找到一篇关于Log4net的教程&#xff1a;log4net Tutorial&#xff0c;这篇博客的作者是&#xff1a;Tim Corey &#xff0c;对应源代码地址为&#xff1a; https://github.com/TimCorey/Log4netTutorial&#xff0c;视频地址为&#xff1a;Ap…...

test-01-java 单元测试框架 junit 入门介绍

JUnit JUnit 是一个用于编写可重复测试的简单框架。 它是 xUnit 架构的一种实例&#xff0c;专门用于单元测试框架。 What to test? NeedDescRight结果是否正确B边界条件是否满足I能反向关联吗C有其他手段交叉检查吗E是否可以强制异常发生P性能问题 maven 入门例子 maven …...

Linux系统中跟TCP相关的系统配置项

TCP连接保活 参考 《Nginx(三) 配置文件详解 - 基础模块》3.18章节 net.ipv4.tcp_keepalive_intvl&#xff1a;设置TCP两次相邻探活检测的间隔时间。默认75秒&#xff0c;单位是秒&#xff0c;对应配置文件/proc/sys/net/ipv4/tcp_keepalive_intvl&#xff1b;net.ipv4.tcp_kee…...

python图片批量下载多线程+超时重试

背景 上篇python入门实战:爬取图片到本地介绍过如何将图片下载到本地,但是实际处理过程中会遇到性能问题:分页数过多下载时间过程、部分页面连接超时无法访问下载失败。本文从实战的角度解释一下如何处理这两个问题。 下载时间过长问题,处理方式是使用多线程,首先回顾…...

冒泡排序之C++实现

描述 冒泡排序算法是一种简单的排序算法&#xff0c;它通过将相邻的元素进行比较并交换位置来实现排序。冒泡排序的基本思想是&#xff0c;每一轮将未排序部分的最大元素逐个向右移动到已排序部分的最右边&#xff0c;直到所有元素都按照从小到大的顺序排列。 冒泡排序的算法…...

【Spring实战】04 Lombok集成及常用注解

文章目录 0. 集成1. Data2. Getter 和 Setter3. NoArgsConstructor&#xff0c;AllArgsConstructor和RequiredArgsConstructor4. ToString5. EqualsAndHashCode6. NonNull7. Builder总结 Lombok 是一款 Java 开发的工具&#xff0c;它通过注解的方式简化了 Java 代码的编写&…...

ubuntu-22.04.3 配置

1.防火墙 a、查看防火墙状态&#xff1a;inactive是关闭&#xff0c;active是开启。 sudo ufw statusb、开启防火墙。 sudo ufw enablec、关闭防火墙。 sudo ufw disable2.设置Ip ifconfigsudo cp /etc/netplan/00-installer-config.yaml /etc/netplan/00-installer-config.y…...

[工具]java_sublime的快速使用

目录 使用 : 怎么运行: 调整字体: 使用 : 新建--->写好代码后-->另存为尾缀是.java的文件 怎么运行: 在你另存为的目录下cmd调用控制台输入dos指令--->执行javac 文件名.java(有.java尾缀)(编译为.class文件)--->java 文件名(没有.class尾缀设计者认为执行的是…...

【银行测试】银行金融测试+金融项目测试点汇总...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、银行金融测试是…...

将PPT的图保持高分辨率导入到Word / WPS中

1、将PPT中画好的图组合在一起&#xff0c;选择组合后的图复制&#xff08;Ctrlc&#xff09; 2、在Word中&#xff0c;选中左上角的粘贴选项--->选择性粘贴 WPS选择元文件 / Word选择增强型图元文件 这样放大也不模糊了...

如何在Spring Boot中优雅地进行参数校验

1. 前言 在平时的开发工作中&#xff0c;我们通常需要对接口进行参数格式验证。当参数个数较少&#xff08;个数小于3&#xff09;时&#xff0c;可以使用if ... else ...手动进行参数验证。当参数个数大于3个时&#xff0c;使用if ... else ...进行参数验证就会让代码显得臃肿…...

图还能有数据库?一文带你了解图数据库是个什么东西!

图数据库 基础 简介 %% 图数据库是图数据库管理系统的简称&#xff0c;是近年来新兴的一种NoSQL数据库使用图形化的模型进行查询的数据库&#xff0c;通过节点、边和属性等方式来表示和存储数据&#xff0c;支持增删改查::CRUD::等操作。图数据库一般用于OLTP系统中&#xf…...

力扣思维题——寻找重复数

题目链接&#xff1a;https://leetcode.cn/problems/find-the-duplicate-number/description/?envTypestudy-plan-v2&envIdtop-100-liked 这题的思维难度较大。一种是利用双指针法进行计算环的起点&#xff0c;这种方法在面试里很难说清楚&#xff0c;也很难想到。大致做…...

基于Kubernetes的jenkins上线

1、基于helm 部署jenkins 要求&#xff1a;当前集群配置了storageClass&#xff0c;并已指定默认的storageClass&#xff0c;一般情况下&#xff0c;创建的storageClass即为默认类 指定默认storageClass的方式 # 如果是新创建默认类&#xff1a; apiVersion: storage.k8s.io/v1…...

每日一题——轮转数组

1. 题目描述 给定一个整数数组nums&#xff0c;将数组中的元素向右轮转k个位置&#xff0c;其中k是非负数。 示例1: 输入&#xff1a;nums [1,2,3,4,5,6,7]&#xff0c;k 3 输出&#xff1a;[5,6,7,1,2,3,4] 解释&#xff1a; 向右轮转 1步&#xff1a;[7,1,2,3,4,5,6] 向右…...

Unity手机移动设备重力感应

Unity手机移动设备重力感应 一、引入二、介绍三、测试成果X Y轴Z轴横屏的手机&#xff0c;如下图竖屏的手机&#xff0c;如下图 一、引入 大家对重力感应应该都不陌生&#xff0c;之前玩过的王者荣耀的资源更新界面就是使用了重力感应的概念&#xff0c;根据手机的晃动来给实体…...

nodejs微信小程序+python+PHP基于推荐算法的电影推荐系统-计算机毕业设计推荐django

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

算法刷题-回溯

今天给大家分享的还是一道关于dfs回溯的问题&#xff0c;对于这类问题大家还是要多刷和总结&#xff0c;总体难度还是偏大。 对于回溯问题有几个关键点&#xff1a; 1.首先对于这类回溯可以节点可以随机选择的问题&#xff0c;要做mian函数中循环调用dfs&#xff08;i&#x…...

高保真组件库:开关

一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...

uniapp获取当前位置和经纬度信息

1.1. 获取当前位置和经纬度信息&#xff08;需要配置高的SDK&#xff09; 调用uni-app官方API中的uni.chooseLocation()&#xff0c;即打开地图选择位置。 <button click"getAddress">获取定位</button> const getAddress () > {uni.chooseLocatio…...