全新的分布式锁,几行代码搞定,简单且强大

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料: 

5cf99004c19923e3de3aa3bb3d455b27.gif

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本 


前言:分布式锁是分布式系统中一个极为重要的工具。目前有多种分布式锁的设计方案,比如借助 redis,mq,数据库,zookeeper 等第三方服务系统来设计分布式锁。tldb 提供的分布式锁,主要是要简化这个设计的过程,提供一个简洁可靠,类似使用程序中对象锁的方式来获取分布式锁。

tldb 提供分布式锁使用方法:

  1. lock 阻塞式请求锁

  2. trylock 尝试加锁,若锁已被占用,则失败返回,反之,则获取该锁

  3. unlock 释放已经获取的锁

    tldb 提供的分布式锁功能主要在 MQ 模块中实现,调用的方法在 MQ 客户端实现,客户端的实现实际非常简单,除了目前已经实现的几种语言 java,golang,python,javaScript 写的 simpleClient,其实其他开发者有兴趣也可以实现其他语言的 MQ 客户端,完全没有技术门槛。分布式锁由 tldb 服务器控制,所以它相对客户端来说,也是跨语言的,如,用 java 客户端上锁的对象,其他语言同样无法获取该对象锁。

Lock (string,int) 方法的使用

tldb 提供的是以字符串为锁对象的独占锁, 如,lock ("abc",3) 必须提供两个参数:

  1. 第一个参数为锁对象,即服务器对 “abc” 对象分配一个锁,所有对 "abc" 对象请求加锁的线程争用一个独占锁,该方法为一个阻塞方法,请求到锁则返回,如果锁被其他线程占用,则一直阻塞直至获取到锁。

  2. 第二个参数为持有该分布式锁的最长时间,单位为秒,例如 lock ("abc",3),意思是,如果超过 3 秒还没有调用 unlock 释放该锁,服务器将强制释放该锁,继续将锁分配给其他请求的线程。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro

  • 视频教程:https://doc.iocoder.cn/video/

UnLock (string) 方法的使用

  • UnLock 为释放分布式锁时调用的方法。客户端在成功获取分布式锁后,服务器会返回一个该锁的 key,客户端执行完逻辑代码的最后,必须显式调用 UnLock (key) 来释放该分布式锁。如果没有调用 unlock 释放锁,tldb 将等待锁释放的超时时间直至超时后强制释放该锁。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud

  • 视频教程:https://doc.iocoder.cn/video/

TryLock (string,int) 方法的使用

  • trylock 与 lock 相似,但是 lock 方法阻塞的,调用 lock 方法请求分布式锁时,如果该锁已经被占用,那么 lock 方法将一直等待直至 tldb 服务器将锁分配给它,这与程序中获取独占锁的方式一致。而 trylock 时非阻塞的,调用 trylock 后会立即返回,如果获取到锁,tldb 会将标识该锁的 key 一并返回,如何该锁已经被占用,服务器将返回空数据。

以下以 go 为例使用分布式锁

因为 tldb 分布式的实现是在 MQ 模块,所以 go 程序必须使用 tlmq-go, tldb 的 mq 客户端进行调用锁方法。

import  "github.com/donnie4w/tlmq-go/cli"

调用 lock 的程序:lock 方法是阻塞的

sc := cli.NewMqClient("ws://127.0.0.1:5001", "mymq=123")
sc.Connect()
//以上为 客户端连接MQ服务器
key, err := sc.Lock("testlock", 3)
//lock中两个参数,第一个参数为字符串,即tldb服务器为“testlock”分配一个全局的分布式锁
//第二个参数3为客户端持有该锁的最长时间,表示超过3秒没有释放锁时,tldb服务器将在服务端强制释放该锁,并分配给其他请求锁的线程
if err!=nil{
    //获取锁失败,需查看tldb能正常访问
}else{
    defer sc.UnLock(key) //获取锁成功后,必须在程序最后调用Unlock
    //执行业务逻辑程序
}

调用 tryLock 的程序,trylock 是非阻塞的

sc := cli.NewMqClient("ws://127.0.0.1:5001", "mymq=123")
sc.Connect()

if key, ok := sc.TryLock("testlock2", 3); ok {
    //ok为true,表示已经成功获取到分布式锁
    defer sc.UnLock(key) //在程序最后释放锁对象
    ...        
}

go 用自旋的方式使用 trylock 获取分布式锁,实现程序的阻塞等待

sc := cli.NewMqClient("ws://127.0.0.1:5001", "mymq=123")
sc.Connect()
var key string
for {
 if  v, ok := sc.TryLock("testlock", 3); ok {
     key = v
  break
 } else {
  <-time.After(100* time.Millisecond)
 }
}
defer sc.UnLock(key)
...//业务逻辑代码

这段程序应该比较易于理解,就是每隔 100 毫秒,循环获取字符串 “testlock” 的分布式锁直至成功。

以下以 java 为例 java 客户端为 tlmq-j :https://github.com/donnie4w/tlmq-j

maven 配置

<dependency>        
   <groupId>io.github.donnie4w</groupId>      
   <artifactId>tlmq-j</artifactId>     
   <version>0.0.2</version>   
</dependency>

调用 lock 方法

MqClient mc = new SimpleClient("ws://127.0.0.1:5001", "mymq=123");
mc.connect();
//java连接服务器
String key = null;
try{
      key = mc.lock("testlock", 3); //获取分布式
      ... //执行业务逻辑程序
}finally {
     if (key!=null){
         mc.unLock(key); //释放分布式锁
     }
}

调用 trylock 方法

MqClient mc = new SimpleClient("ws://127.0.0.1:5001", "mymq=123");
mc.connect();
String key = null;
try{
      key = mc.tryLock("testlock", 3); //获取分布式
      ... //执行业务逻辑程序
} finally {
     if (key!=null){
         mc.unLock(key); //释放分布式锁
     }               
}

以下是 tldb 分布式锁的功能测试数据: 多线程并发 调用 lock 获取同一个对象锁后,程序的运行数据:

0cefb85ddecc209ebcfdca2f1b19b061.png

多线程并发使用自旋的方式调用 trylock 与 lock 获取同一个对象锁:

b970406dbb9e4eddf12cec48433acc09.png

欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

9c42e289923c2911ff8c0910b8309c33.png

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

d15be63eaeeb7387e5fbfd42d5ee5151.png

c08f81ea2b5d4b2185f29e218315d625.png5511187385bd2c182db7a65b2610a44f.png4598ba22c1e85e5372365b97b01b1bad.png91e1577296ea72442984576a2db92430.png

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值