全新的分布式锁,功能简单且强大

news/2024/11/13 2:40:22/

分布式锁是分布式系统中一个极为重要的工具。

目前有多种分布式锁的设计方案,比如借助 redis,mq,数据库,zookeeper 等第三方服务系统来设计分布式锁。

tldb 提供的分布式锁,主要是要简化这个设计的过程,提供一个简洁可靠,类似使用程序中对象锁的方式来获取分布式锁。

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

  • lock 阻塞式请求锁

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

  • 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 释放该锁,服务器将强制释放该锁,继续将锁分配给其他请求的线程。

UnLock (string) 方法的使用

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

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 获取同一个对象锁后,程序的运行数据:

图片

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

图片

最后说一句(求关注!别白嫖!)

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记  就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!


http://www.ppmy.cn/news/1394589.html

相关文章

动态规划16 | ● 583. 两个字符串的删除操作 ● *72. 编辑距离

583. 两个字符串的删除操作 https://programmercarl.com/0583.%E4%B8%A4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%88%A0%E9%99%A4%E6%93%8D%E4%BD%9C.html 考点 子序列问题 我的思路 dp[i][j]的含义是&#xff0c;当两个字符串分别取前i和j个元素时&#xff0c;对应…

详解JavaScript中this指向

this 原理 this 是一个指针型变量&#xff0c;它指向当前函数的运行环境。 1.内存的数据结构 var obj { foo: 5 };2.函数 var obj { foo: function () {} };引擎会将函数单独保存在内存中&#xff0c;然后再将函数的地址赋值给foo属性的value属性。 由于函数是一个单独的…

一些规律、现象

图文部分由COPILOT生成。 规律详情 墨菲定律 墨菲定律(Murphys Law) 一件事可能出错时就一定会出错。 图&#xff1a;AI生成 破窗效应 破窗效应(Broken windows theory&#xff09;是犯罪心理学理论。以一幢有少许破窗的建筑为例&#xff0c;如果那些窗没修理好&#xff0…

如何学好Python语言

学习Python&#xff1a;一场充满探索与实践的编程之旅 Python&#xff0c;作为一种解释型、交互式和面向对象的编程语言&#xff0c;近年来在数据科学、人工智能、Web开发等多个领域得到了广泛的应用。掌握Python&#xff0c;不仅可以提升个人的编程技能&#xff0c;还能够为未…

C语言动态内存的管理

前言 本篇博客就来探讨一下动态内存&#xff0c;说到内存&#xff0c;我们以前开辟空间大小都是固定的&#xff0c;不能调整这个空间大小&#xff0c;于是就有动态内存&#xff0c;可以让我们自己选择开辟多少空间&#xff0c;更加方便&#xff0c;让我们一起来看看动态内存的有…

MC0207 中转站

物流业为了降低物流成本&#xff0c;提高物流效率&#xff0c;运输过程中通常不会由始发地直达目的地&#xff0c;而是经由多个中转站中转&#xff0c;最终到达目的地。最常见的便是快递业&#xff0c;由于中转站有很多&#xff0c;要想将所有中转站两两互通代价过高&#xff0…

.NET高级面试指南专题二十二【 数据库索引】

数据库索引是一种数据结构&#xff0c;用于提高数据库查询效率。它们类似于书籍的目录&#xff0c;能够快速指引数据库引擎去查找特定的数据行。 索引的原理是通过在数据库表的列上创建一个有序的数据结构&#xff0c;通常是 B 树或 B 树&#xff0c;使得数据库引擎可以更快地定…

第三十一章 配置 Web Gateway 的默认参数 - 事件记录参数

文章目录 第三十一章 配置 Web Gateway 的默认参数 - 事件记录参数 第三十一章 配置 Web Gateway 的默认参数 - 事件记录参数 事件日志级别字段指定 Web Gateway 写入 Web Gateway 事件日志的信息。日志记录选项定义为一串字符&#xff0c;每个字符代表一个日志记录命令。此处…