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

Redis锁与幂等性不得不说的故事

前言:

相信很多小伙伴对缓存锁都不陌生,但是简单的缓存锁想要用好还是需要一些功力。本文总结了笔者多年使用缓存所的一些心得,欢迎交流探讨~

幂等模型:

幂等场景一般由查重+写入两步操作组成,两步操作组成一个最小完整逻辑,再通过缓存锁保证原子性

实现:

实现redis分布式锁需要注意两个关键点:保证原子性、设置过期时间

保证原子性的目的:是为了保证同一时间只有一个请求能获取到锁

设置过期时间的目的:是为了防止解锁失败导致死锁

public class MethodLock {private static final Logger logger = LoggerFactory.getLogger(MethodLock.class);public static final String KEY_SEPARATOR = ":";public static final String PARAM_SEPARATOR = "_";public static final String KEY_PARAM_SEPARATOR = "#";public static final String SET_SUCCESS_RESULT = "OK";public static final String METHOD_LOCK = "doraemon:method:lock";private static Jedis jedis;private static Jedis getJedis() {if (jedis == null) {jedis = 自行实现;}return jedis;}/*** 获取锁** @param methodName 方法名,类名加方法名(例:MethodLock.getLock)* @param timeout    锁过期时间(单位秒)* @param params     参数(通过参数控制锁的粒度)* @return*/public static boolean getLock(String methodName, long timeout, String... params) {String method = "getLock|获取锁|";try {String key = getKey(methodName, params);String result = getJedis().set(key, methodName, "nx", "ex", timeout <= 0 ? 5 : timeout);if (Objects.equals(SET_SUCCESS_RESULT, result)) {return true;}} catch (Exception e) {logger.error(method + "执行失败,methodName={},timeout={},params={}", methodName, timeout, JSONObject.toJSONString(params), e);}return false;}/*** 释放锁** @param methodName 方法名,类名加方法名(例:MethodLock.getLock)* @param params     参数(通过参数控制锁的粒度)* @return*/public static boolean delLock(String methodName, String... params) {String method = "delLock|释放锁|";try {String key = getKey(methodName, params);long result = getJedis().del(key);if (result > 0) {return true;}} catch (Exception e) {logger.error(method + "执行失败,methodName={},params={}", methodName, JSONObject.toJSONString(params), e);}return false;}/*** 【私有方法】获取redis key** @param methodName* @param params* @return*/protected static String getKey(String methodName, String... params) {if (StringUtils.isBlank(methodName)) {return null;}String key = METHOD_LOCK + KEY_SEPARATOR + methodName;if (params != null && params.length > 0) {key += KEY_PARAM_SEPARATOR + Joiner.on(PARAM_SEPARATOR).useForNull("null").join(params);}return key;}

注意事项:

1、锁范围内的逻辑需要 完整+精简

锁范围内指的是:获取锁和释放锁中间的逻辑,只有必须保证原子性的关键的逻辑才能放入到锁范围内,其他的一些不相关逻辑完全可以放在锁范围外处理

完整:加锁的目的是为了解决并发问题,所以锁里面的逻辑要求完整,不完整的逻辑=没加锁

比如幂等场景下:一般是 查重+写入 两个操作需要保证原子性,这两个操作加起来就是一个完整逻辑

精简:精简的意思是在保证完整的前提下,不要有多余的逻辑,以免锁占用时间过长,进而影响性能

2、锁粒度选择要恰当

锁粒度指的是:锁对请求条件筛选的粗细程度,例如用户购买商品下单时可以 1、根据用户id加锁,2、也可以根据用户id + 商品id加锁,1和2就是两种粒度

锁的粒度太大会导致锁的范围过大,可能会影响当前逻辑之外的业务

锁的粒度太小会导致锁的范围过小,可能会导致锁失效

3、锁过期时间设置要合理

一般建议过期时间 = 逻辑执行时间 * 150%

过期时间太小可能导致在逻辑执行完成前,锁过期失效

过期时间太大+解锁失败,可能导致在锁过期失效之前重试的请求被拒之门外

4、加锁在try之前,锁中的逻辑使用try catch包围,解锁在finally里处理

若加锁操作在try catch中,并发场景下未获取锁的操作会执行到finally里将锁解除,影响正常逻辑

防止逻辑中出现异常,阻断流畅,导致解锁操作执行不到

5、基于redis的分布式锁并不100%可靠

在一些特殊情况下,比如redis宕机,数据丢失,可能会导致锁失效

相关文章:

Redis锁与幂等性不得不说的故事

前言&#xff1a; 相信很多小伙伴对缓存锁都不陌生&#xff0c;但是简单的缓存锁想要用好还是需要一些功力。本文总结了笔者多年使用缓存所的一些心得&#xff0c;欢迎交流探讨~ 幂等模型&#xff1a; 幂等场景一般由查重写入两步操作组成&#xff0c;两步操作组成一个最小完…...

Spark 应用调优

Spark 应用调优人数统计优化摇号次数分布优化Shuffle 常规优化数据分区合并加 Cache优化中签率的变化趋势中签率局部洞察优化倍率分析优化表信息 : apply : 申请者 : 事实表lucky : 中签者表 : 维度表两张表的 Schema ( batchNum&#xff0c;carNum ) : ( 摇号批次&#xff0c…...

synchronized 与 volatile 关键字

目录1.前言1.synchronized 关键字1. 互斥2.保证内存可见性3.可重入2. volatile 关键字1.保证内存可见性2.无法保证原子性3.synchronized 与 volatile 的区别1.前言 synchronized关键字和volatile是大家在Java多线程学习时接触的两个关键字&#xff0c;很多同学可能学习完就忘记…...

【0成本搭建个人博客】——Hexo+Node.js+Gitee Pages

目录 1、下载安装Git 2、下载安装Node.js 3、使用Hexo进行博客的搭建 4、更改博客样式 5、将博客上传到Gitee 6、更新博客 首先看一下Hexo的博客的效果。 1、下载安装Git Git 是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本…...

【面试实战】认证授权流程及原理分析

认证授权流程及原理分析 1、认证 (Authentication) 和授权 (Authorization)的区别是什么?2、什么是Cookie ? Cookie的作用是什么?如何在服务端使用 Cookie ?3、Cookie 和 Session 有什么区别?如何使用Session进行身份验证?1、认证 (Authentication) 和授权 (Authorizatio…...

TPM命令解析之tpm2_startauthsession

参考网址链接&#xff1a;tpm2-tools/tpm2_startauthsession.1.md at master tpm2-software/tpm2-tools GitHub 命令名称 tpm2_startauthsession 功能 启动一个TPM会话。 命令形式 tpm2_startauthsession [OPTIONS] 描述 启动一个TPM会话。默认是启动一个试验&#xff08…...

第14章 局部波动率模型

这学期会时不时更新一下伊曼纽尔德曼&#xff08;Emanuel Derman&#xff09; 教授与迈克尔B.米勒&#xff08;Michael B. Miller&#xff09;的《The Volatility Smile》这本书&#xff0c;本意是协助导师课程需要&#xff0c;发在这里有意的朋友们可以学习一下&#xff0c;思…...

云原生周刊:开源“赢了”,但它可持续吗?

日前召开的 State of Open 会议上&#xff0c;开源“赢了”&#xff0c;但如果政府和企业不站出来确保生态系统在未来的弹性和可持续性&#xff0c;那么它仍然会失败。 OpenUK 首席执行官 Amanda Brock 在开幕式上表示&#xff0c;数字化和开源在过去 5 到 10 年的进步提升了工…...

读《企业IT架构转型之道》

本书还没读完&#xff0c;暂摘抄一些概念&#xff0c;因为自身做的新系统也在转型&#xff0c;从单体式到一体化一年来遇到很多问题有技术上的&#xff0c;也有团队协作的&#xff0c;过程是痛苦且复杂的&#xff0c;所以在刚翻阅前几十页时候&#xff0c;对于淘宝技术团队转型…...

Qt中的QTcpSocket、QWebSocket和QLocalSocket

同时实现了QTcpSocket、QWebSocket和QLocalSocket的简单通讯deamon&#xff0c;支持自动获取本机ip&#xff0c;多个客户端交互。在这个基础上你可以自己加错误检测、心跳发送、包封装解析和客户端自动重连等功能。 获取本机电脑ip&#xff1a; QString Widget::getIp() {QSt…...

枚举学习贴

1. 概述 1.1 是什么 枚举对应英文(enumeration, 简写 enum)枚举是一组常量的集合。可以这里理解&#xff1a;枚举属于一种特殊的类&#xff0c;里面只包含一组有限的特定的对象 1.2 枚举的二种实现方式 自定义类实现枚举使用 enum 关键字实现枚举 1.3 什么时候用 存在有限…...

【C++】30h速成C++从入门到精通(继承)

继承的概念及定义继承的概念继承&#xff08;inheritance&#xff09;机制是面向对象程序设计使代码可以复用的重要手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象程序…...

Java多线程还不会的进来吧,为你量身打造

&#x1f497;推荐阅读文章&#x1f497; &#x1f338;JavaSE系列&#x1f338;&#x1f449;1️⃣《JavaSE系列教程》&#x1f33a;MySQL系列&#x1f33a;&#x1f449;2️⃣《MySQL系列教程》&#x1f340;JavaWeb系列&#x1f340;&#x1f449;3️⃣《JavaWeb系列教程》…...

8 神经网络及Python实现

1 人工神经网络的历史 1.1 生物模型 1943年&#xff0c;心理学家W.S.McCulloch和数理逻辑学家W.Pitts基于神经元的生理特征&#xff0c;建立了单个神经元的数学模型&#xff08;MP模型&#xff09;。 1.2 数学模型 ykφ(∑i1mωkixibk)φ(WkTXb)y_{k}\varphi\left(\sum_{i1…...

使用QIS(Quantum Image Sensor)图像重建总结(1)

最近看了不少使用QIS重建图像的文章&#xff0c;觉得比较完整详细的还是Abhiram Gnanasambandam的博士论文&#xff1a;https://hammer.purdue.edu/articles/thesis/Computer_vision_at_low_light/20057081 1 介绍 讲述了又墨子的小孔成像原理&#xff0c;到交卷相机&#xf…...

【SpringCloud】SpringCloud教程之Nacos实战(二)

目录前言一.Nacos实现配置管理二.Nacos拉取配置三.Nacos配置热更新(自动刷新&#xff0c;不需要重启服务)1.在有Value注入变量所在类添加注解2.新建类用于属性加载和配置热更新四.Nacos多环境配置共享1.多环境共享配置2.配置的加载优先级测试3.配置优先级前言 Nacos实战一&…...

利用Qemu工具仿真ARM64平台

Windows系统利用Qemu仿真ARM64平台0 写在最前1 Windows安装Qemu1.1 下载Qemu1.2 安装Qemu1.3 添加环境变量1.4测试安装是否成功2. Qemu安装Ubuntu-Server-Arm-642.1 安装前的准备2.2 安装Ubuntu server arm 64位镜像3 Windows配置Qemu网络和传输文件3.1 参考内容3.2 Windows安装…...

【Hello Linux】进程控制 (内含思维导图)

作者&#xff1a;小萌新 专栏&#xff1a;Linux 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;简单介绍下进程的控制 包括进程启动 进程终止 进程等待 进程替换等概念 进程控制介绍进程创建fork函数fork函数的返回值fork函数的使用…...

嵌入式linux物联网毕业设计项目智能语音识别基于stm32mp157开发板

stm32mp157开发板FS-MP1A是华清远见自主研发的一款高品质、高性价比的Linux单片机二合一的嵌入式教学级开发板。开发板搭载ST的STM32MP157高性能微处理器&#xff0c;集成2个Cortex-A7核和1个Cortex-M4 核&#xff0c;A7核上可以跑Linux操作系统&#xff0c;M4核上可以跑FreeRT…...

【黄河流域公安院校网络空间安全技能挑战赛】部分wp

文章目录webbabyPHPfunnyPHPEzphp**遍历文件目录的类**1、DirectoryIterator&#xff1a;2、FilesystemIterator:3、**Globlterator**读取文件内容的类&#xff1a;SplFileObjectMisc套娃web babyPHP <?php highlight_file(__FILE__); error_reporting(0);$num $_GET[nu…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...