redis分布式锁的应用

redis 作为分布式锁的东西 分布式锁的应用
redis,zk,数据库这些都可以实现分布式锁
我们今天主要基于redis实现的分布式锁,而且要求性能要好
基于一个小的业务场景来说,就比如说秒杀中的减库存,防止超卖

在这里插入图片描述

这种代码就会有并发问题,比方说3个线程  同时查出来 之后会set 299  此时就超卖了
这就是我们典型的超卖问题,我们可以加锁,比如说我们常见的sy,JVM进程级别的锁

在这里插入图片描述

这样就可以解决我们的问题,如果说我们此时上线部署之后就一台服务器,也就一个tomcat 
单机环境 是没有问题 假设我们做集群项目的时候 此时就会出现问题
我们的项目基本上都是 基于nginx 进行转发,利用nginx做负载均衡,
在nginx的upstream中配置负载均衡的地址

在这里插入图片描述

一般来说我们都会搞这些集群架构部署,这种场景下我们jvm 级别锁就不可用了
我们可以模拟高并发场景利用jmeter基于高并发下发请求
jmeter--->nginx---->tomcat1/tomcat2
发现如果此时利用jvm级别的锁就会出现问题

在这里插入图片描述

一般情况下这种问题要解决的话 就用分布式锁 分布式锁 可以用redis
我们一般使用redis的setnx来实现分布式锁
基于setnx命令我们就可以实现一个分布式锁,在redis这边 只会有1个请求执行成功
这样我们就写完了

在这里插入图片描述

我们基于这种简单的setnx 实现的分布式锁有什么问题呢
Q1 如果我第一个线程拿到锁执行一半的时候 就会抛异常 抛异常之后 我就不会delete掉了
这个时候就相当于死锁了,key永远在redis中  其他线程要想来执行就会执行不成功

在这里插入图片描述

我写个try catch finally 意思是如果跑异常了 我还可以执行redis.delete 	
如果现在执行一半后 客户端宕机了,或者被运维重启了,呢么此时finally也是不能被执行的,我们可以设置一个超时时间,比方说10s,

在这里插入图片描述

我们可以加个超时时间,意味着如果你业务宕机了,过段时间 redis内部自己就释放锁了
如果并发特别大的情况下.这种代码也会造成超卖,在并发情况下 接口的响应可能会变慢如果线程一执行了一半,超时时间到了, 这个时候线程2就会进来,然后此时线程一就会吧线程2的这个锁解开
线程1 删除(释放了)了线程2的锁  此时就会出现问题
出这个问题的根本点就在于  我自己加的锁被别人释放了

在这里插入图片描述

我们可以加个uuid就是说 我只能释放我自己加的锁,这个时候的代码就很完善了

在这里插入图片描述

假设一个线程枷锁成功了执行到这行代码的时候,卡顿一会,我们的10s到期了
其他线程又可以基于这个Lock进行加锁,这个时候线程1还是释放了线程2的锁
所以我们要保证这2行代码的原子性我们的业务没有执行完毕 锁的超时时间就结束了
针对于分布式锁 有个锁续命机制 
分线程给锁进行续命,判断主线程有没有业务执行完毕,如果没有结束就续命
每过10s之后就续命,我的主线程一直执行 我的锁就不会失效,因为他一直被分线程做续命操作
以后我主线程要是把锁释放了,分线程会判断锁还被主线程持有 如果持有 就会做续命操作
如果不持有就不再跑任务了
Redisson  就实现了这种机制 

在这里插入图片描述

lock.lock 就可以获取得到锁了
Lock.unLock 加锁 解锁
https://www.cnblogs.com/xiaoyangabc/p/16906922.html
redis枷锁的核心流程, 假设有2个线程同时都是一个key执行  redis调用他的lock方法
只有1个线程执行成功,假设线程1执行成功。 线程2 执行没有成功
他会whlie循环自璇  尝试加锁
线程1 加锁成功 他会另外开启一个分线程,分线程就会对这个key 进行续命,
这就是整个redis分布式锁续命的核心业务流程

在这里插入图片描述

redis分布式锁底层是基于Lua脚本来写的,
lua脚本,减少网络开销。可以批量执行redis命令,类似于管道可以把一批命令打包发给redis 服务端去执行
比如说原来有4条命令,我就需要发送4次远程交互(网络调用)
但是我用管道或者lua脚本的话 就只需要一次网络调用
对于Lua脚本也一样,假设我有10条redis命令,我也可以放到lua脚本来一次性发给服务端去执行
lua脚本是支持原子操作的,一段Lua脚本,要么同时成功,要么同时失败
lua脚本都执行完毕 之后 其他命令才可以执行(因为redis服务端是单线程来执行任务的)
我这个命令执行的中间是不可以被其他线程插入的
Lua  支持事务在redis中可以执行lua脚本
用lua脚本是个原子操作

在这里插入图片描述
在这里插入图片描述

redis分布式锁的原理,当多个线程进行抢锁时候,只有一个线程来设置成功,其他没有抢到锁的线程就会while自旋尝试加锁,通过lua脚本进行加锁,加锁成功后就会对其进行续命,加锁失败就会自璇,续命锁
(Lua脚本进行续命) 每次续命1/3(判断主线程持有的呢吧锁是否还存在,如果存在我就进行续命,吧主线程的超时时间重新设置为30S ,如果不存在,我就结束)说白了redis实现分布式锁的核心东西也就完成了,基本上是基于Lua来实现的  借助redis的单线程帮我们实现原子性.来解决并发问题

当我们其他线程如果没有加锁成功,lock 没有加锁成功会怎么办.假设有10个线程while循环枪锁 他的cpu 就会100%,如果说我们redis 没有抢到锁 他自选再去加锁 他是怎么来做的
其他线程会返回锁剩余加锁时间的剩余时间 并且阻塞让出cpu比如说第一个线程执行了5S之后
假设我我第二个线程会尝试的过来加锁 如果没有加锁成功会再这里等25S  阻塞等待会让出cpu
25s过后之后再尝试加锁while循环间断性的加锁
假设有1000个线程来了同时超时 同时while循环  此时是非公平锁 也就是redis 默认 是非公平锁

在这里插入图片描述

所以 多个线程来抢锁时,底层会基于lua脚本进行加锁,但是只有一个线程来加锁成功,抢锁成功后后台开启一个分线程来对其进行续命,其他线程如果没有抢到锁 会while尝试加锁 但是 并不是死循环
而是会阻塞等待,返回第一次尝试加锁返回的时间,并且此时会让出cpu片段如果此时业务时间比较快,快速吧这把锁释放了. 呢我其他线程不能一直阻塞 在解锁的方法中有一个唤醒机制 通过redis的发布订阅 他会往Queue发消息
没有加锁成功的线程会去监听Queue,呢么其他线程就会唤醒阻塞  继而继续while循环继续抢锁

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

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

相关文章

uni-app开发

uni-app 官方手册:uni-app官网 一:tarBar:一级导航栏,即 tab 切换时显示对应页。 在pages.json文件里写入如下代码: 此效果:

编译工具链 之一 基本概念、组成部分、编译过程、命名规则

编译工具链将程序源代码翻译成可以在计算机上运行的可执行程序。编译过程是由一系列的步骤组成的,每一个步骤都有一个对应的工具。这些工具紧密地工作在一起,前一个工具的输出是后一个工具的输入,像一根链条一样,我们称这一系列工…

Unity 单例-接口模式

单例-接口模式 使用接口方式实现的单例可以继承其它类&#xff0c;更加方便 using System.Collections; using System.Collections.Generic; using UniRx; using UniRx.Triggers; using UnityEngine; namespace ZYF {public interface ISingleton<TMono> where TMono : M…

力扣第55题 跳跃游戏 c++ 贪心 + 覆盖 加暴力超时参考

题目 55. 跳跃游戏 中等 相关标签 贪心 数组 动态规划 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &…

Unity编辑器扩展 --- AssetPostprocessor资源导入自动设置

unity导入资源的编辑器设置: 防止策划资源乱导入,资源导入需要的格式&#xff0c;统一资源管理 AssetPostprocessor资源导入管线 AssetPostprocessor用于在资源导入时自动做一些设置&#xff0c;比如当导入大量图片时&#xff0c;自动设置图片的类型&#xff0c;大小等。Ass…

AlDente Pro for Mac: 掌控电池充电的终极解决方案

你是否曾经为了保护你的MacBook的电池&#xff0c;而苦恼于无法控制它的充电速度&#xff1f;AlDente Pro for Mac 是一款专为Mac用户设计的电池管理工具&#xff0c;它能帮助你解决这个问题。 AlDente Pro for Mac 是一款电池最大充电限制软件&#xff0c;它能够让你自由地设…

【数据结构与算法】二叉树的运用要点

目录 一&#xff0c;二叉树的结构深入认识 二&#xff0c;二叉树的遍历 三&#xff0c;二叉树的基本运算 3-1&#xff0c;计算二叉树的大小 3-2&#xff0c;统计二叉树叶子结点个数 3-3&#xff0c;计算第k层的节点个数 3-4&#xff0c;查找指定值的结点 一&#xff0c;二叉…

ResNet论文精读,代码实现与拓展知识

文章目录 ResNet 论文精读代码实现网络可视化代码 拓展知识 ResNets残差的调参残差链接的渊源残差链接有效性的解释ResNet 深度ResNeXt代码实现 能够提点的技巧「Warmup」「Label-smoothing」「Random image cropping and patching」「Knowledge Distiallation」「Cutout」「Ra…

Centos 7 Zabbix配置安装

前言 Zabbix是一款开源的网络监控和管理软件&#xff0c;具有高度的可扩展性和灵活性。它可以监控各种网络设备、服务器、虚拟机以及应用程序等&#xff0c;收集并分析性能指标&#xff0c;并发送警报和报告。Zabbix具有以下特点&#xff1a; 1. 支持多种监控方式&#xff1a;可…

SAP POorPI RFC接口字段调整后需要的操作-针对SP24及以后的PO系统

文章目录 问题描述解决办法 问题描述 在SAP系统的RFC接口结构中添加了字段&#xff0c;RFC也重新引用到了PO系统&#xff0c;Cache和CommunicationChannel都刷新或启停了&#xff0c;但是新增的字段在调用接口的时候数据进不到SAP系统&#xff0c;SAP系统内的值也出不来。经过…

postgresql14-模式的管理(三)

基本概念 postgresql成为数据库管理系统DBMS&#xff0c;在内存中以进程的形态运行起来成为一个实例&#xff0c;可管理多个database。 数据库databases&#xff1a;包含表、索引、视图、存储过程&#xff1b; 模式schema&#xff1a;多个对象组成一个模式&#xff0c;多个模…

nodejs+vue大学生社团管理系统

通过软件的需求分析已经获得了系统的基本功能需求&#xff0c;根据需求&#xff0c;将大学生社团管理系统平台功能模块主要分为管理员模块。管理员添加社团成员管理、社团信息管理&#xff0c;社长管理、用户注册管理等操作。 目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1…

JVM的几个面试重点

JVM的内存区域划分 JVM类加载机制 前言 Java程序最开始是一个 .java 的文件&#xff0c;JVM把它编译成 .closs 文件&#xff08;字节码文件&#xff09;&#xff0c;运行 Java 程序&#xff0c; JVM 就会读取 .class 文件&#xff0c;把文件内容读取到内存中&#xff0c;构造出…

多线程与高并发

1.线程创建的3种方式 2.线程的状态切换步骤 3.线程的5中状态 Java中的线程的生命周期大体可分为5种状态。 1. 新建(NEW)&#xff1a;新创建了一个线程对象。 2. 可运行(RUNNABLE)&#xff1a;线程对象创建后&#xff0c;其他线程(比如main线程&#xff09;调用了该对象的sta…

通义大模型使用指南之通义千问

一、注册 我们可以打开以下网站&#xff0c;用手机号注册一个账号即可。 通义大模型 (aliyun.com) 二、使用介绍 如图&#xff0c;我们可以看到有三个大项功能&#xff0c;通义千问、通义万相、通义听悟。下来我们体验一下通义千问的功能。 1、通义千问 通义千问主要有两个功能…

北邮22级信通院数电:Verilog-FPGA(6)第六周实验:全加器

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 先抄作业&#xff01;&#xff01;&#xff01;&am…

人工智能算法PPT学习

YOLO You only look once 是一种图像识别算法&#xff0c;速度较快。高效、灵活、泛化性能好&#xff0c;在工业中较为受欢迎。 图像金字塔 一幅图像的多个不同分辨率的子图构成的图像集合。是通过一个图像不断的降低采样率产生的&#xff0c;最小的图像可能仅仅有一个像素点…

如何在Ubuntu下安装RabbitMQ服务并异地远程访问?

文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基…

Elasticsearch 8.X 分词插件版本更新不及时解决方案

1、关于 Elasticsearch 8.X IK 分词插件相关问题 球友在 ElasticSearch 版本选型问题中提及&#xff1a;如果要使用ik插件&#xff0c;是不是就使用目前最新的IK对应elasticsearch的版本“8.8.2”&#xff1f; https://github.com/medcl/elasticsearch-analysis-ik/releases/ta…

强大的虚拟机软件 VMware Fusion Pro 13中文最新 for mac

VMware Fusion Pro是一款虚拟化软件&#xff0c;它允许在Mac电脑上同时运行Windows和其他操作系统&#xff0c;而无需重启电脑&#xff0c;它采用了领先的虚拟化技术&#xff0c;能够保证在Mac电脑在同时运行多个操作系统时表现出极高的效率和稳定性。 VMware Fusion Pro具有以…