我是哑巴
嗯,每当我们在本地系统中工作时,一切都像黄油一样工作。这就是为什么我们称“没有比 127.0.0.1 更好的地方了”,但醒来面对现实
生产中的事情并不总是按预期进行。大多数情况下,当您运行应用程序的多个实例时。
?正如您所看到的,如果我们的应用程序的多个实例正在运行,并且假设我们的客户端发出请求,将用户标记为数据库中的付费用户。
- 客户端将请求我们的服务器
- 请求将到达我们的负载均衡器
- 其中一个实例将收到请求并向我们的数据库发出写入查询
看起来还不错吧?到目前为止没问题吧。
嗯,是的,到目前为止没有问题。但是如果我们想编写这样的业务逻辑怎么办:-
- 从数据库中获取用户
- 检查用户是否是免费用户或已付费
- 如果免费,则将其标记为付费并保存在数据库中
- 如果已付款,请在回复中发送“已付款”。
⚡️ 众所周知(假设我们在这里使用 MySQL)MySQL 数据库符合 ACID,这意味着任何查询都将是原子的和隔离的。这意味着 MySQL 查询将以原子方式运行,要么通过,要么失败。但中间不会退出。
?但这里有一个问题。想想,想想……
- 第 1 步:我们正在获取用户(原子事务)
- 第 2 步:在代码中运行一些业务逻辑
- 第3步:如果用户未付款则更新MySQL记录(原子交易)
如果在第 2 步,又有一个取消付款的请求,然后该查询首先运行并将用户标记为免费,然后运行第 3 步并将用户标记为已付费,将会发生什么情况。
??万岁,用户甚至无需付费即可访问我们的产品。
锁定
✅救星Locks来了
?锁是一种结构,一次只允许一个线程进入临界区(不应被多个工作线程访问的代码块)
因此,我们将在操作完成之前获取锁定并在操作完成后释放:-
- 第0步:尝试获取()锁
- 第 1 步:如果获取,我们将获取用户(原子事务)
- 第 2 步:在代码中运行一些业务逻辑
- 第3步:如果用户未付款则更新MySQL记录(原子事务)
- 第四步:release() 锁
?问题
现在,问题来了,如果我们使用一些内存锁数据结构或任何基于内存的锁,它将适合我们的应用程序的一个实例。其他运行相同代码并在数据库中更新的实例怎么样?
分布式锁的概念来了
?分布式锁
这里的锁充当一种集中式服务,如果我们服务的一个实例获取了锁,那么其他实例就无法使用同一个密钥。
支付服务中可以使用什么键?
?对于进行付款的用户,密钥可以是=“PAYMENT_”+ user_id + amount
的组合这对于每个用户来说都是唯一的。并且当用户付款或取消付款时,该密钥将保持不变。因此,当一个操作发生时,其他操作无法继续,因为这两个操作将尝试获取同一键。
? Key、获取锁、释放锁到底是什么?最重要的是,redis 是如何使用的?
?使用Redis实现分布式锁
使用 Redis 的单个实例:-
但是单个 Redis 实例存在以下几个问题:-
- 单个实例可能会失败并且获取的锁可能无法释放
- 如果使用两个实例(主副本),则一个客户端将获取一个实例上的锁
- 主服务器必须与副本进行相同的通信才能同步。这种通信本身就是异步通信
?因此,如果在主服务器上获取了锁,并且在与副本通信时,如果主服务器在与副本同步之前发生故障。副本将成为主服务器,其中同一密钥上的锁将可用于获取之前在主服务器上获取的锁。
即使有两个实例(主副本),我们服务的两个实例也将能够获取 Redis 上的锁。
使用 Redlock 算法:-
获取锁:- 我们将尝试在具有锁过期时间的多个 Redis 实例上获取锁
锁验证:- 如果主要 Redis 实例为客户端获取了锁,则将被视为已获取锁
释放锁:- 释放锁时,所有实例都释放锁
是的,就是这样。
❤️ 感谢您的阅读,并订阅我们的时事通讯以获取更多此类文章:- https://www.serversidedigest.com/
欲了解更多信息:-
- Java 中的 Jedis:- https://redis.io/docs/latest/develop/connect/clients/java/jedis/
- Golang 中的 Redis 客户端:- https://github.com/redis/go-redis
以上是如何使用Redis实现分布式锁的详细内容。更多信息请关注PHP中文网其他相关文章!

本文分析了2025年的前四个JavaScript框架(React,Angular,Vue,Susve),比较了它们的性能,可伸缩性和未来前景。 尽管由于强大的社区和生态系统,所有这些都保持占主导地位,但它们的相对人口

本文讨论了使用咖啡因和Guava缓存在Java中实施多层缓存以提高应用程序性能。它涵盖设置,集成和绩效优势,以及配置和驱逐政策管理最佳PRA

本文介绍了SnakeyAml中的CVE-2022-1471漏洞,这是一个允许远程代码执行的关键缺陷。 它详细介绍了如何升级春季启动应用程序到Snakeyaml 1.33或更高版本的降低风险,强调了依赖性更新

Java的类上载涉及使用带有引导,扩展程序和应用程序类负载器的分层系统加载,链接和初始化类。父代授权模型确保首先加载核心类别,从而影响自定义类LOA

Node.js 20通过V8发动机改进可显着提高性能,特别是更快的垃圾收集和I/O。 新功能包括更好的WebSembly支持和精制的调试工具,提高开发人员的生产率和应用速度。

本文探讨了在黄瓜步骤之间共享数据的方法,比较方案上下文,全局变量,参数传递和数据结构。 它强调可维护性的最佳实践,包括简洁的上下文使用,描述性

本文使用lambda表达式,流API,方法参考和可选探索将功能编程集成到Java中。 它突出显示了通过简洁性和不变性改善代码可读性和可维护性等好处


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

Atom编辑器mac版下载
最流行的的开源编辑器

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Dreamweaver Mac版
视觉化网页开发工具