首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Nacos 核心原理解读+高性能微服务系统实战-无密分享

核心代码,注释必读

// download:3w 52xueit com

vue 2.x 响应式

Object.defineProperty

爱学it学无止境

在分布式系统中,分布式锁是确保资源互斥访问的重要机制。我们在系统中修改已有数据时,需要先读取,然后进行修改保存,此时很容易遇到并发问题。由于修改和保存不是原子操作,在并发场景下,部分对数据的操作可能会丢失。在单服务器系统我们常用本地锁来避免并发带来的问题,然而,当服务采用集群方式部署时,本地锁无法在多个服务器之间生效,这时候保证数据的一致性就需要分布式锁来实现。

实现方式

通过 Redis 的 ​​SET​​ 和 ​​DEL​​ 命令实现锁的设置和释放,并使用 Lua 脚本确保操作的原子性。

加锁命令:SETNX key value,当键不存在时,对键进行设置操作并返回成功,否则返回失败。KEY 是锁的唯一标识,一般按业务来决定命名。

解锁命令:DEL key,通过删除键值对释放锁,以便其他线程可以通过 SETNX 命令来获取锁。

锁超时:EXPIRE key timeout, 设置 key 的超时时间,以保证即使锁没有被显式释放,锁也可以在一定时间后自动释放,避免资源被永远锁住。

以下是详细的代码分析:

获取锁

​​getLock​​ 方法尝试获取锁。它使用 Redis 的 ​​SET​​ 命令,并通过 Lua 脚本确保操作的原子性。关键点如下:

锁超时:设置 key 的超时时间,以保证即使锁没有被显式释放,锁也可以在一定时间后自动释放,避免资源被永远锁住。

唯一值生成:使用 ​​md5(uniqid('', true))​​ 生成唯一的锁值,在后面释放锁时需要用到。

原子性:​​SET​​ 命令结合 ​​NX​​ 和 ​​EX​​ 选项确保锁的唯一性和过期时间。Lua 脚本避免了多命令操作的并发问题。

重试机制:如果锁获取失败,方法会自旋重试,直到达到最大重试次数。每次重试之间,线程会等待 200 毫秒。

释放锁

​​releaseLock​​ 方法用于释放锁。它通过 Lua 脚本实现,确保只有持有锁的客户端才能释放锁。关键点如下:

锁误解除:如果线程 A 成功获取到了锁,并且设置了过期时间 30 秒,但线程 A 执行时间超过了 30 秒,锁过期自动释放,此时线程 B 获取到了锁;随后 A 执行完成,线程 A 使用 DEL 命令来释放锁,但此时线程 B 加的锁还没有执行完成,线程 A 实际释放的线程 B 加的锁。所以我们要获取当前锁的值并检查是否与传入的 ​​lockValue​​ 匹配。如果匹配,则执行 ​​DEL​​ 命令释放锁。这样可以防止误删其他客户端持有的锁。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OsDU5msCRGjeiuGR3DFqa4JA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券