摘要:分布式鎖分布式鎖一般用在分布式系統(tǒng)或者多個(gè)應(yīng)用中,用來(lái)控制同一任務(wù)是否執(zhí)行或者任務(wù)的執(zhí)行順序。分布式鎖的實(shí)現(xiàn)方式使用的和使用的使用的創(chuàng)建節(jié)點(diǎn)使用的創(chuàng)建臨時(shí)序列節(jié)點(diǎn)使用的和來(lái)實(shí)現(xiàn)分布式鎖如果不存在,設(shè)置為當(dāng)前的值為如果存在,直接返回。
1.分布式鎖
分布式鎖一般用在分布式系統(tǒng)或者多個(gè)應(yīng)用中,用來(lái)控制同一任務(wù)是否執(zhí)行或者任務(wù)的執(zhí)行順序。在項(xiàng)目中,部署了多個(gè)tomcat應(yīng)用,在執(zhí)行定時(shí)任務(wù)時(shí)就會(huì)遇到同一任務(wù)可能執(zhí)行多次的情況,我們可以借助分布式鎖,保證在同一時(shí)間只有一個(gè)tomcat應(yīng)用執(zhí)行了定時(shí)任務(wù)。
2.分布式鎖的實(shí)現(xiàn)方式使用redis的setnx()和expire()
使用redis的getset()
使用zookeeper的創(chuàng)建節(jié)點(diǎn)node
使用zookeeper的創(chuàng)建臨時(shí)序列節(jié)點(diǎn)
3.使用redis的setnx()和expire()來(lái)實(shí)現(xiàn)分布式鎖setnx(key,value) 如果key不存在,設(shè)置為當(dāng)前key的值為value;如果key存在,直接返回。 expire()來(lái)設(shè)置超時(shí)時(shí)間
定義注解類:
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Lockable{ // redis緩存key String key(); // redis緩存key中的數(shù)據(jù) String value() default ""; // 過期時(shí)間(秒),默認(rèn)為一分鐘 long expire() default 60; }
定時(shí)任務(wù)增加注解@Lockable:
@Lockable(key = "DistributedLock:dealExpireRecords") public void dealExpireRecords() { }
定義一個(gè)aop切面LockAspect,使用@Around處理所有注解為@Lockable的方法,通過連接點(diǎn)確認(rèn)此注解是用在方法上,通過方法獲取注解信息,使用setIfAbsent來(lái)判斷是否獲取分布式鎖,如果沒有獲取分布式鎖,直接返回;如果獲取到分布式鎖,通過expire設(shè)置過期時(shí)間,并調(diào)用指定方法。
@Component @Slf4j @Aspect public class LockAspect { @Autowired private RedisTemplate redisTemplate; @Around("@annotation(com.records.aop.Lockable)") public Object distributeLock(ProceedingJoinPoint pjp) { Object resultObject = null; //確認(rèn)此注解是用在方法上 Signature signature = pjp.getSignature(); if (!(signature instanceof MethodSignature)) { log.error("Lockable is method annotation!"); return resultObject; } MethodSignature methodSignature = (MethodSignature) signature; Method targetMethod = methodSignature.getMethod(); //獲取注解信息 Lockable lockable = targetMethod.getAnnotation(Lockable.class); String key = lockable.key(); String value = lockable.value(); long expire = lockable.expire(); // 分布式鎖,如果沒有此key,設(shè)置此值并返回true;如果有此key,則返回false boolean result = redisTemplate.boundValueOps(key).setIfAbsent(value); if (!result) { //其他程序已經(jīng)獲取分布式鎖 return resultObject; } //設(shè)置過期時(shí)間,默認(rèn)一分鐘 redisTemplate.boundValueOps(key).expire(expire, TimeUnit.SECONDS); try { resultObject = pjp.proceed(); //調(diào)用對(duì)應(yīng)方法執(zhí)行 } catch (Throwable throwable) { throwable.printStackTrace(); } return resultObject; } }4.使用redis的getset()來(lái)實(shí)現(xiàn)分布式鎖
此方法使redisTemplate.boundValueOps(key).getAndSet(value)的方法,如果返回空,表示獲取了分布式鎖;如果返回不為空,表示分布式鎖已經(jīng)被其他程序占用
5.使用zookeeper的創(chuàng)建節(jié)點(diǎn)node使用zookeeper創(chuàng)建節(jié)點(diǎn)node,如果創(chuàng)建節(jié)點(diǎn)成功,表示獲取了此分布式鎖;如果創(chuàng)建節(jié)點(diǎn)失敗,表示此分布式鎖已經(jīng)被其他程序占用(多個(gè)程序同時(shí)創(chuàng)建一個(gè)節(jié)點(diǎn)node,只有一個(gè)能夠創(chuàng)建成功)
6.使用zookeeper的創(chuàng)建臨時(shí)序列節(jié)點(diǎn)使用zookeeper創(chuàng)建臨時(shí)序列節(jié)點(diǎn)來(lái)實(shí)現(xiàn)分布式鎖,適用于順序執(zhí)行的程序,大體思路就是創(chuàng)建臨時(shí)序列節(jié)點(diǎn),找出最小的序列節(jié)點(diǎn),獲取分布式鎖,程序執(zhí)行完成之后此序列節(jié)點(diǎn)消失,通過watch來(lái)監(jiān)控節(jié)點(diǎn)的變化,從剩下的節(jié)點(diǎn)的找到最小的序列節(jié)點(diǎn),獲取分布式鎖,執(zhí)行相應(yīng)處理,依次類推......
本文主要介紹了使用redis和zookeeper實(shí)現(xiàn)分布式鎖的處理,也可以關(guān)注我的公眾號(hào):不知風(fēng)在何處,相互溝通,共同進(jìn)步。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/67331.html
摘要:分布式鎖實(shí)現(xiàn)方式前言目前幾乎很多大型網(wǎng)站及應(yīng)用都是分布式部署的,分布式場(chǎng)景中的數(shù)據(jù)一致性問題一直是一個(gè)比較重要的話題。基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布式鎖基于緩存等實(shí)現(xiàn)分布式鎖基于實(shí)現(xiàn)分布式鎖。 前言 分布式鎖,是控制分布式系統(tǒng)之間同步訪問共享資源的一種方式 在分布式系統(tǒng)中,常常需要協(xié)調(diào)他們的動(dòng)作。如果不同的系統(tǒng)或是同一個(gè)系統(tǒng)的不同主機(jī)之間共享了一個(gè)或一組資源,那么訪問這些資源的時(shí)候,往往需要互斥...
摘要:分布式鎖實(shí)現(xiàn)方式前言目前幾乎很多大型網(wǎng)站及應(yīng)用都是分布式部署的,分布式場(chǎng)景中的數(shù)據(jù)一致性問題一直是一個(gè)比較重要的話題。基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布式鎖基于緩存等實(shí)現(xiàn)分布式鎖基于實(shí)現(xiàn)分布式鎖。 前言 分布式鎖,是控制分布式系統(tǒng)之間同步訪問共享資源的一種方式 在分布式系統(tǒng)中,常常需要協(xié)調(diào)他們的動(dòng)作。如果不同的系統(tǒng)或是同一個(gè)系統(tǒng)的不同主機(jī)之間共享了一個(gè)或一組資源,那么訪問這些資源的時(shí)候,往往需要互斥...
摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語(yǔ)言和等其他語(yǔ)言的對(duì)比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問到的持久化與恢復(fù)實(shí)現(xiàn)故障恢復(fù)自動(dòng)化詳解哨兵技術(shù)查漏補(bǔ)缺最易錯(cuò)過的技術(shù)要點(diǎn)大掃盲意外宕機(jī)不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語(yǔ)言和Java、python等其他語(yǔ)言的對(duì)比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...
閱讀 943·2021-09-07 09:58
閱讀 1494·2021-09-07 09:58
閱讀 2888·2021-09-04 16:40
閱讀 2508·2019-08-30 15:55
閱讀 2416·2019-08-30 15:54
閱讀 1374·2019-08-30 15:52
閱讀 438·2019-08-30 10:49
閱讀 2610·2019-08-29 13:21