springcloud如何用Redlock實現分布式鎖_第1頁
springcloud如何用Redlock實現分布式鎖_第2頁
springcloud如何用Redlock實現分布式鎖_第3頁
springcloud如何用Redlock實現分布式鎖_第4頁
springcloud如何用Redlock實現分布式鎖_第5頁
已閱讀5頁,還剩3頁未讀, 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第springcloud如何用Redlock實現分布式鎖目錄一、redlock簡介二、怎么用java使用redlock三、參考資料之前寫過一篇文章《如何在springcloud分布式系統中實現分布式鎖?》,由于自己僅僅是閱讀了相關的書籍,和查閱了相關的資料,就認為那樣的是可行的。那篇文章實現的大概思路是用setNx命令和setEx配合使用。setNx是一個耗時操作,因為它需要查詢這個鍵是否存在,就算redis的百萬的qps,在高并發的場景下,這種操作也是有問題的。關于redis實現分布式鎖,redis官方推薦使用redlock。

一、redlock簡介

在不同進程需要互斥地訪問共享資源時,分布式鎖是一種非常有用的技術手段。實現高效的分布式鎖有三個屬性需要考慮:

安全屬性:互斥,不管什么時候,只有一個客戶端持有鎖

效率屬性A:不會死鎖

效率屬性B:容錯,只要大多數redis節點能夠正常工作,客戶端端都能獲取和釋放鎖。

Redlock是redis官方提出的實現分布式鎖管理器的算法。這個算法會比一般的普通方法更加安全可靠。關于這個算法的討論可以看下官方文檔。

二、怎么用java使用redlock

在pom文件引入redis和redisson依賴:

!--redis--

dependency

groupIdorg.springframework.boot/groupId

artifactIdspring-boot-starter-data-redis/artifactId

/dependency

!--redisson--

dependency

groupIdorg.redisson/groupId

artifactIdredisson/artifactId

version3.3.2/version

/dependency

AquiredLockWorker接口類,,主要是用于獲取鎖后需要處理的邏輯:

*Createdbyfangzhipengon2017/4/5.

*獲取鎖后需要處理的邏輯

publicinterfaceAquiredLockWorkerT{

TinvokeAfterLockAquire()throwsException;

}

DistributedLocker獲取鎖管理類:

*Createdbyfangzhipengon2017/4/5.

*獲取鎖管理類

publicinterfaceDistributedLocker{

*獲取鎖

*@paramresourceName鎖的名稱

*@paramworker獲取鎖后的處理類

*@paramT

*@return處理完具體的業務邏輯要返回的數據

*@throwsUnableToAquireLockException

*@throwsException

TTlock(StringresourceName,AquiredLockWorkerTworker)throwsUnableToAquireLockException,Exception;

TTlock(StringresourceName,AquiredLockWorkerTworker,intlockTime)throwsUnableToAquireLockException,Exception;

}

UnableToAquireLockException,不能獲取鎖的異常類:

*Createdbyfangzhipengon2017/4/5.

*異常類

publicclassUnableToAquireLockExceptionextendsRuntimeException{

publicUnableToAquireLockException(){

publicUnableToAquireLockException(Stringmessage){

super(message);

publicUnableToAquireLockException(Stringmessage,Throwablecause){

super(message,cause);

}

RedissonConnector連接類:

*Createdbyfangzhipengon2017/4/5.

*獲取RedissonClient連接類

@Component

publicclassRedissonConnector{

RedissonClientredisson;

@PostConstruct

publicvoidinit(){

redisson=Redisson.create();

publicRedissonClientgetClient(){

returnredisson;

}

RedisLocker類,實現了DistributedLocker:

importorg.redisson.api.RLock;

importorg.redisson.api.RedissonClient;

importorg.springframework.beans.factory.annotation.Autowired;

importorg.springframework.stereotype.Component;

importjava.util.concurrent.TimeUnit;

*Createdbyfangzhipengon2017/4/5.

@Component

publicclassRedisLockerimplementsDistributedLocker{

privatefinalstaticStringLOCKER_PREFIX="lock:";

@Autowired

RedissonConnectorredissonConnector;

@Override

publicTTlock(StringresourceName,AquiredLockWorkerTworker)throwsInterruptedException,UnableToAquireLockException,Exception{

returnlock(resourceName,worker,100);

@Override

publicTTlock(StringresourceName,AquiredLockWorkerTworker,intlockTime)throwsUnableToAquireLockException,Exception{

RedissonClientredisson=redissonConnector.getClient();

RLocklock=redisson.getLock(LOCKER_PREFIX+resourceName);

//Waitfor100secondssecondsandautomaticallyunlockitafterlockTimeseconds

booleansuccess=lock.tryLock(100,lockTime,TimeUnit.SECONDS);

if(success){

try{

returnworker.invokeAfterLockAquire();

}finally{

lock.unlock();

thrownewUnableToAquireLockException();

}

測試類:

@Autowired

RedisLockerdistributedLocker;

@RequestMapping(value="/redlock")

publicStringtestRedlock()throwsException{

CountDownLatchstartSignal=newCountDownLatch(1);

CountDownLatchdoneSignal=newCountDownLatch(5);

for(inti=0;i++i){//createandstartthreads

newThread(newWorker(startSignal,doneSignal)).start();

startSignal.countDown();//letallthreadsproceed

doneSignal.await();

System.out.println("Allprocessorsdone.Shutdownconnection");

return"redlock";

classWorkerimplementsRunnable{

privatefinalCountDownLatchstartSignal;

privatefinalCountDownLatchdoneSignal;

Worker(CountDownLatchstartSignal,CountDownLatchdoneSignal){

this.startSignal=startSignal;

this.doneSignal=doneSignal;

publicvoidrun(){

try{

startSignal.await();

distributedLocker.lock("test",newAquiredLockWorkerObject(){

@Override

publicObjectinvokeAfterLockAquire(){

doTask();

returnnull;

}catch(Exceptione){

voiddoTask(){

System.out.println(Thread.currentThread().getName()+"start");

Randomrandom=newRandom();

int_int=random.nextInt(200);

System.out.println(Thread.currentThread().getName()+"sleep"+_int+"millis");

try{

Thread.sleep(_int);

}catch(InterruptedExceptione){

e.printStackTrace();

System.out.println(Thread.currentThread().getName()+"end");

doneSignal.countDown();

}

運行測試類:

Thread-48start

Thread-48sleep99millis

Thread-48end

Thread-49start

Thread-49sleep118millis

Thread-49end

Thread-52start

Thread-52sleep141millis

Thread-52end

Thread-50start

Thread-50sleep28millis

Thread-50end

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論