0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

tldb提供分布式锁使用方法

OSC开源社区 来源:OSCHINA 社区 2023-11-02 14:44 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

作者:donnie4w

前言:分布式锁是分布式系统中一个极为重要的工具。目前有多种分布式锁的设计方案,比如借助 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) 必须提供两个参数:

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

第二个参数为持有该分布式锁的最长时间,单位为秒,例如 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 配置

        
   io.github.donnie4w      
   tlmq-j     
   0.0.2   

调用 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 获取同一个对象锁后,程序的运行数据:
ecea2568-771a-11ee-939d-92fbcf53809c.png

多线程并发使用自旋的方式调用 trylock 与 lock 获取同一个对象锁:
ed0aad24-771a-11ee-939d-92fbcf53809c.png

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    13

    文章

    10093

    浏览量

    90855
  • 数据库
    +关注

    关注

    7

    文章

    3993

    浏览量

    67712
  • 字符串
    +关注

    关注

    1

    文章

    594

    浏览量

    23033
  • 代码
    +关注

    关注

    30

    文章

    4940

    浏览量

    73116

原文标题:全新的分布式锁,功能简单且强大

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Redis 分布式的正确实现方式

    分布式一般有三种实现方式:1. 数据库乐观;2. 基于Redis的分布式;3. 基于ZooKeeper的
    的头像 发表于 05-31 14:19 4049次阅读

    Java:Redis分布式的原理和案例

    要介绍分布式,首先要提到与分布式锁相对应的是线程、进程
    的头像 发表于 07-01 11:49 4355次阅读

    为什么需要分布式 基于Zookeeper安全吗

    这篇文章我想和你聊一聊,关于 Redis 分布式的「安全性」问题。 Redis 分布式的话题,很多文章已经写烂了,我为什么还要写这篇文章呢? 因为我发现网上 99% 的文章,并没有
    的头像 发表于 08-10 18:06 6019次阅读

    Redis分布式有什么特性

    今天我们聊聊分布式。 1. 分布式是什么? 我们的手机有、车有、家门有
    的头像 发表于 10-12 16:42 2758次阅读

    Redis分布式真的安全吗?

    今天我们来聊一聊Redis分布式
    的头像 发表于 11-02 14:07 1383次阅读

    深入理解redis分布式

    深入理解redis分布式 哈喽,大家好,我是指北君。 本篇文件我们来介绍如何Redis实现分布式的演进过程,以及为什么不能直接用Setnx实现
    的头像 发表于 10-08 14:13 1589次阅读
    深入理解redis<b class='flag-5'>分布式</b><b class='flag-5'>锁</b>

    Redis实现分布式的几种方案

    本文将介绍什么是分布式,以及使用Redis实现分布式的几种方案。 前言 了解分布式之前,需
    的头像 发表于 10-11 15:19 1159次阅读

    什么是分布式 Redis的五种分布式方案

    本地加锁的方式在分布式的场景下不适用,所以本文我们来探讨下如何引入分布式解决本地的问题。本篇所有代码和业务基于我的开源项目 PassJava。
    发表于 10-23 11:35 2392次阅读
    什么是<b class='flag-5'>分布式</b><b class='flag-5'>锁</b> Redis的五种<b class='flag-5'>分布式</b><b class='flag-5'>锁</b>方案

    redis分布式可能出现的问题

    Redis分布式是一种常用的机制,用于解决多个进程或多台服务器对共享资源的并发访问问题。然而,由于分布式环境的复杂性,使用Redis分布式
    的头像 发表于 11-16 11:40 2036次阅读

    redis分布式死锁处理方案

    中,Redis分布式也可能遭遇死锁问题,即多个线程相互等待对方释放的情况。本文将详细介绍Redis分布式死锁的原因,并
    的头像 发表于 11-16 11:44 2590次阅读

    redis分布式三个方法

    Redis是一种高性能的分布式缓存和键值存储系统,它提供了一种可靠的分布式解决方案。在分布式系统中,由于多个节点之间的并发访问,需要使用
    的头像 发表于 12-04 11:22 2128次阅读

    如何实现Redis分布式

    Redis是一个开源的内存数据存储系统,可用于高速读写操作。在分布式系统中,为了保证数据的一致性和避免竞态条件,常常需要使用分布式来对共享资源进行加锁操作。Redis提供了一种简单而
    的头像 发表于 12-04 11:24 1255次阅读

    redis分布式可能出现的问题及解决方案

    Redis分布式是一种常见的解决分布式系统中并发问题的方案。虽然Redis分布式锁具有许多优点,但也存在一些潜在的问题需要注意。本文将详细介绍Redis
    的头像 发表于 12-04 11:29 1832次阅读

    redis分布式的缺点

    Redis分布式是一种常见的用于解决分布式系统中资源争用问题的解决方案。尽管Redis分布式锁具有很多优点,但它也存在一些缺点。本文将从几个方面详细介绍Redis
    的头像 发表于 12-04 14:05 2034次阅读

    分布式的三种实现方式

    分布式的三种实现方式  分布式是在分布式系统中用于实现对共享资源进行访问控制的一种机制。分布式
    的头像 发表于 12-28 10:01 1518次阅读