作者: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 獲取同一個對象鎖后,程序的運行數據:

多線程并發使用自旋的方式調用 trylock 與 lock 獲取同一個對象鎖:

審核編輯:湯梓紅
-
服務器
+關注
關注
12文章
9547瀏覽量
86830 -
數據庫
+關注
關注
7文章
3874瀏覽量
65420 -
字符串
+關注
關注
1文章
588瀏覽量
20839 -
代碼
+關注
關注
30文章
4868瀏覽量
69900
原文標題:全新的分布式鎖,功能簡單且強大
文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
為什么需要分布式鎖 基于Zookeeper鎖安全嗎
什么是分布式鎖 Redis的五種分布式鎖方案

評論