文檔資料: wenku.itilzj.com
1、概述
在多線程的環(huán)境下,為了保證一個(gè)代碼塊在同一時(shí)間只能由一個(gè)線程訪問(wèn),Java中我們一般可以使用synchronized
語(yǔ)法和ReentrantLock
去保證,這實(shí)際上是本地鎖的方式。而在如今分布式架構(gòu)的熱潮下,如何保證不同節(jié)點(diǎn)的線程同步執(zhí)行呢?
實(shí)際上,對(duì)于分布式場(chǎng)景,我們可以使用分布式鎖,分布式鎖是用于分布式環(huán)境下并發(fā)控制的一種機(jī)制,用于控制某個(gè)資源在同一時(shí)刻只能被一個(gè)應(yīng)用所使用。
「互斥性:」同一時(shí)刻只能有一個(gè)線程持有鎖。
「可重入性:」同一節(jié)點(diǎn)上的同一個(gè)線程如果獲取了鎖之后能夠再次獲取鎖。
「鎖超時(shí):」類(lèi)似于J.U.C中的鎖,支持鎖超時(shí),以防止死鎖。
「高性能和高可用:」加鎖和解鎖需要高效,并且需要保證高可用性,防止分布式鎖失效。
「具備阻塞和非阻塞性:」能夠及時(shí)從阻塞狀態(tài)中被喚醒。
2、Redis粗糙實(shí)現(xiàn)
Redis本身可以被多個(gè)客戶端共享訪問(wèn),是一個(gè)共享存儲(chǔ)系統(tǒng),適合用來(lái)保存分布式鎖。由于Redis的讀寫(xiě)性能高,可以應(yīng)對(duì)高并發(fā)的鎖操作場(chǎng)景。
Redis的SET
命令有一個(gè)NX
參數(shù),可以實(shí)現(xiàn)「key不存在才插入」,因此可以用它來(lái)實(shí)現(xiàn)分布式鎖:
如果key不存在,則表示插入成功,可以用來(lái)表示加鎖成功;
如果key存在,則表示插入失敗,可以用來(lái)表示加鎖失??;
當(dāng)需要解鎖時(shí),只需刪除對(duì)應(yīng)的key即可解鎖成功;
為了避免死鎖,需要設(shè)置合適的過(guò)期時(shí)間。
這樣描述,我們可以得到一個(gè)十分粗糙的分布式鎖實(shí)現(xiàn)。
// 嘗試獲得鎖
if (setnx(key, 1) == 1){
// 獲得鎖成功,設(shè)置過(guò)期時(shí)間
expire(key, 30)
try {
//TODO 業(yè)務(wù)邏輯
} finally {
// 解鎖
del(key)
然而,上述實(shí)現(xiàn)方式存在一些問(wèn)題,使其不能被稱為合格的分布式鎖:
「非原子性操作:」多條命令的操作不是原子性的,可能會(huì)導(dǎo)致死鎖的產(chǎn)生。
「鎖誤解除:」存在鎖誤解除的可能性,即在持有鎖的線程在內(nèi)部出現(xiàn)阻塞時(shí),鎖的TTL到期導(dǎo)致自動(dòng)釋放,而其他線程誤解除鎖的情況。
「業(yè)務(wù)超時(shí)自動(dòng)解鎖導(dǎo)致并發(fā)問(wèn)題:」由于業(yè)務(wù)超時(shí)自動(dòng)解鎖,可能導(dǎo)致并發(fā)問(wèn)題的發(fā)生。
「分布式鎖不可重入:」實(shí)現(xiàn)的分布式鎖不支持重入。
3、解決遺留問(wèn)題
3.1誤刪情況
在以下情況下可能會(huì)出現(xiàn)誤刪情況:
持有鎖的線程1在鎖的內(nèi)部出現(xiàn)了阻塞,導(dǎo)致其鎖的TTL到期從而鎖自動(dòng)釋放;
此時(shí)線程2嘗試獲取鎖,由于線程1已經(jīng)釋放了鎖,線程2可以拿到;
但是隨后線程1解除阻塞,繼續(xù)執(zhí)行并開(kāi)始釋放鎖;
此時(shí)可能會(huì)將屬于線程2的鎖釋放,導(dǎo)致誤刪別人鎖的情況。
為了解決這個(gè)問(wèn)題,需要在釋放鎖的時(shí)候確保只有持有鎖的線程才能釋放對(duì)應(yīng)的鎖,可以通過(guò)在鎖中添加標(biāo)識(shí)來(lái)實(shí)現(xiàn)。
對(duì)應(yīng)的解決方案也很簡(jiǎn)單,既然是一個(gè)線程誤刪了別人的鎖,就相當(dāng)于把別人的廁所門(mén)給誤開(kāi)了,那么在開(kāi)門(mén)之前校驗(yàn)一下這扇門(mén)是不是自己關(guān)上的不就好了:
在存入鎖的時(shí)候,放入自己的線程標(biāo)識(shí);
在刪除鎖的時(shí)候,判斷當(dāng)前這把鎖是不是自己存入的:
如果是,則進(jìn)行刪除;
如果不是,則不進(jìn)行刪除。
這樣就可以確保只有持有鎖的線程才能釋放對(duì)應(yīng)的鎖,有效地避免了誤刪別人鎖的情況。
// 嘗試獲得鎖
if (setnx(key, "當(dāng)前線程號(hào)") == 1) {
// 獲得鎖成功,設(shè)置過(guò)期時(shí)間
expire(key, 30);
try {
// TODO 業(yè)務(wù)邏輯
} finally {
// 解鎖
if ("當(dāng)前線程號(hào)".equals(get(key))) {
del(key);
同時(shí),這種方式也能夠?qū)⒎植际芥i改造成可重入的分布式鎖,在獲取鎖的時(shí)候判斷一下是否是當(dāng)前線程獲取的鎖,鎖標(biāo)識(shí)自增便可。
3.2、原子性保證
前面說(shuō)到,SETNX和EXPIRE操作是非原子性的。如果SETNX成功,還未設(shè)置鎖超時(shí)時(shí)間時(shí),由于服務(wù)器掛掉、重啟或網(wǎng)絡(luò)問(wèn)題等原因,導(dǎo)致EXPIRE命令沒(méi)有執(zhí)行,鎖沒(méi)有設(shè)置超時(shí)時(shí)間就有可能會(huì)導(dǎo)致死鎖產(chǎn)生。
同時(shí),對(duì)于上面解決的誤刪問(wèn)題,如果以下極端情況同樣會(huì)出現(xiàn)并發(fā)問(wèn)題:
假設(shè)線程1已經(jīng)獲取了鎖,在判斷標(biāo)識(shí)一致之后,準(zhǔn)備釋放鎖的時(shí)候,又出現(xiàn)了阻塞(例如JVM垃圾回收機(jī)制);
于是鎖的TTL到期了,自動(dòng)釋放了;
現(xiàn)在線程2趁虛而入,拿到了一把鎖;
但是線程1的邏輯還沒(méi)執(zhí)行完,那么線程1就會(huì)執(zhí)行刪除鎖的邏輯;
但是在阻塞前線程1已經(jīng)判斷了標(biāo)識(shí)一致,所以現(xiàn)在線程1把線程2的鎖給誤刪了;
這就相當(dāng)于判斷標(biāo)識(shí)那行代碼沒(méi)有起到作用;
因?yàn)榫€程1的獲取鎖、判斷標(biāo)識(shí)、刪除鎖,不是原子操作,所以我們要防止剛剛的情況。
對(duì)于Redis中并沒(méi)有對(duì)應(yīng)的原子性API提供給我們進(jìn)行調(diào)用,但是我們可以通過(guò)Lua腳本對(duì)Redis 功能進(jìn)行拓展。
-- 過(guò)期時(shí)間設(shè)置
if (redis.call('setnx', KEYS[1], ARGV[1]) < 1) then
return 0;
end;
redis.call('expire', KEYS[1], tonumber(ARGV[2]));
return 1;
-- 刪除鎖
-- 比較鎖中的線程標(biāo)識(shí)與線程標(biāo)識(shí)是否一致
if (redis.call('get', KEYS[1]) == ARGV[1]) then
-- 一致則釋放鎖
return redis.call('del', KEYS[1])
end;
return 0
以上就是原子性保證的lua腳本實(shí)現(xiàn),通過(guò)Java調(diào)用 call 方法執(zhí)行l(wèi)ua腳本即可通過(guò)lua腳本 實(shí)現(xiàn)原子性操作從而解決該問(wèn)題。
3.3、超時(shí)自動(dòng)解鎖
雖然上面解決了誤刪和原子性問(wèn)題,但是如果獲取鎖的線程阻塞時(shí)間超過(guò)了設(shè)置的TTL,那么該自動(dòng)解鎖還是得自動(dòng)解鎖。
對(duì)于這種情況,一個(gè)簡(jiǎn)單粗暴的方法就是把過(guò)期時(shí)間設(shè)置得很長(zhǎng),在設(shè)置的TTL內(nèi),能夠保證邏輯一定能夠執(zhí)行完。但是這種方式和不設(shè)置TTL一樣,如果發(fā)生意外宕機(jī)之類(lèi)的情況,下一個(gè)線程將會(huì)阻塞很長(zhǎng)時(shí)間,十分不優(yōu)雅。
因此,針對(duì)這個(gè)問(wèn)題,我們可以給線程單獨(dú)開(kāi)一個(gè)守護(hù)線程,去檢測(cè)當(dāng)前線程運(yùn)行情況。如果TTL即將到期,由守護(hù)線程對(duì)TTL進(jìn)行續(xù)期,保證當(dāng)前線程能夠正確地執(zhí)行完業(yè)務(wù)邏輯。
綜上所述,基于 Redis 節(jié)點(diǎn)實(shí)現(xiàn)分布式鎖時(shí),我們至少需要實(shí)現(xiàn)以下需求:
加鎖/解鎖包括了讀取鎖變量、檢查鎖變量值和設(shè)置鎖變量值三個(gè)操作,但需要以原子操作的方式完成;
鎖變量需要設(shè)置過(guò)期時(shí)間,以免客戶端拿到鎖后發(fā)生異常,導(dǎo)致鎖一直無(wú)法釋放出現(xiàn)死鎖,所以,我們?cè)?SET 命令執(zhí)行時(shí)加上 EX/PX 選項(xiàng),設(shè)置其過(guò)期時(shí)間;
鎖變量的值需要能區(qū)分來(lái)自不同客戶端的加鎖操作,以免在釋放鎖時(shí),出現(xiàn)誤釋放操作,所以,我們使用 SET 命令設(shè)置鎖變量值時(shí),每個(gè)客戶端設(shè)置的值是一個(gè)唯一值,用于標(biāo)識(shí)客戶端。
4、Redis實(shí)現(xiàn)優(yōu)缺
「基于 Redis 實(shí)現(xiàn)分布式鎖的優(yōu)點(diǎn):」
「性能高效:」這是選擇緩存實(shí)現(xiàn)分布式鎖最核心的出發(fā)點(diǎn)。
「實(shí)現(xiàn)方便:」很多研發(fā)工程師選擇使用 Redis 來(lái)實(shí)現(xiàn)分布式鎖,很大成分上是因?yàn)?Redis 提供了 setnx 方法,實(shí)現(xiàn)分布式鎖很方便。
「避免單點(diǎn)故障:」因?yàn)?Redis 是跨集群部署的,自然就避免了單點(diǎn)故障。
「基于 Redis 實(shí)現(xiàn)分布式鎖的缺點(diǎn):」
「超時(shí)時(shí)間不好設(shè)置:」如果鎖的超時(shí)時(shí)間設(shè)置過(guò)長(zhǎng),會(huì)影響性能,如果設(shè)置的超時(shí)時(shí)間過(guò)短會(huì)保護(hù)不到共享資源。對(duì)于這種情況可以使用前面提及到的守護(hù)線程進(jìn)行續(xù)期操作使得鎖得過(guò)期時(shí)間得到保障。
「Redis 主從復(fù)制模式中的數(shù)據(jù)是異步復(fù)制的,」這樣導(dǎo)致分布式鎖的不可靠性。如果在 Redis 主節(jié)點(diǎn)獲取到鎖后,在沒(méi)有同步到其他節(jié)點(diǎn)時(shí),Redis 主節(jié)點(diǎn)宕機(jī)了,此時(shí)新的 Redis 主節(jié)點(diǎn)依然可以獲取鎖,所以多個(gè)應(yīng)用服務(wù)就可以同時(shí)獲取到鎖。
5、集群?jiǎn)栴}
5.1、主從集群
為了保證 Redis 的可用性,一般采用主從方式部署。主從數(shù)據(jù)同步有異步和同步兩種方式, Redis 將指令記錄在本地內(nèi)存 buffer 中,然后異步將 buffer 中的指令同步到從節(jié)點(diǎn),從節(jié)點(diǎn)一邊執(zhí)行同步的指令流來(lái)達(dá)到和主節(jié)點(diǎn)一致的狀態(tài),一邊向主節(jié)點(diǎn)反饋同步情況。如果這個(gè) master 節(jié)點(diǎn)由于某些原因發(fā)生了主從切換,那么就會(huì)出現(xiàn)鎖丟失的情況:
在 Redis 的 master 節(jié)點(diǎn)上拿到了鎖;
但是這個(gè)加鎖的 key 還沒(méi)有同步到 slave 節(jié)點(diǎn);
master 故障,發(fā)生故障轉(zhuǎn)移,slave 節(jié)點(diǎn)升級(jí)為 master 節(jié)點(diǎn);
導(dǎo)致鎖丟失。
集群腦裂指因?yàn)榫W(wǎng)絡(luò)問(wèn)題,導(dǎo)致 Redis master 節(jié)點(diǎn)跟 slave 節(jié)點(diǎn)和 sentinel 集群處于不同的網(wǎng)絡(luò)分區(qū),因?yàn)?sentinel 集群無(wú)法感知到 master 的存在,所以將 slave 節(jié)點(diǎn)提升為 master 節(jié)點(diǎn),此時(shí)存在兩個(gè)不同的 master 節(jié)點(diǎn)。Redis Cluster 集群部署方式同理。
總結(jié)來(lái)說(shuō)腦裂就是由于網(wǎng)絡(luò)問(wèn)題,集群節(jié)點(diǎn)之間失去聯(lián)系。主從數(shù)據(jù)不同步;重新平衡選舉,產(chǎn)生兩個(gè)主服務(wù)。等網(wǎng)絡(luò)恢復(fù),舊主節(jié)點(diǎn)會(huì)降級(jí)為從節(jié)點(diǎn),再與新主節(jié)點(diǎn)進(jìn)行同步復(fù)制的時(shí)候,由于從節(jié)點(diǎn)會(huì)清空自己的緩沖區(qū),所以導(dǎo)致之前客戶端寫(xiě)入的數(shù)據(jù)丟失了
當(dāng)不同的客戶端連接不同的 master 節(jié)點(diǎn)時(shí),兩個(gè)客戶端可以同時(shí)擁有同一把鎖
6、RedLock
為了保證集群環(huán)境下分布式鎖的可靠性,Redis 官方已經(jīng)設(shè)計(jì)了一個(gè)分布式鎖算法 Redlock(紅鎖)。它是基于多個(gè) Redis 節(jié)點(diǎn)的分布式鎖,即使有節(jié)點(diǎn)發(fā)生了故障,鎖變量仍然是存在的,客戶端還是可以完成鎖操作。官方推薦是至少部署 5 個(gè) Redis 節(jié)點(diǎn),而且都是主節(jié)點(diǎn),它們之間沒(méi)有任何關(guān)系,都是一個(gè)個(gè)孤立的節(jié)點(diǎn)。
Redlock 算法的基本思路,是讓客戶端和多個(gè)獨(dú)立的 Redis 節(jié)點(diǎn)依次請(qǐng)求申請(qǐng)加鎖,如果客戶端能夠和半數(shù)以上的節(jié)點(diǎn)成功地完成加鎖操作,那么我們就認(rèn)為,客戶端成功地獲得分布式鎖,否則加鎖失敗。
這樣一來(lái),即使有某個(gè) Redis 節(jié)點(diǎn)發(fā)生故障,因?yàn)殒i的數(shù)據(jù)在其他節(jié)點(diǎn)上也有保存,所以客戶端仍然可以正常地進(jìn)行鎖操作,鎖的數(shù)據(jù)也不會(huì)丟失。
為了取到鎖,客戶端應(yīng)該執(zhí)行以下操作:
獲取當(dāng)前Unix時(shí)間,以毫秒為單位。
依次嘗試從5個(gè)實(shí)例,使用相同的key和具有唯一性的value(例如UUID)獲取鎖。當(dāng)向 Redis請(qǐng)求獲取鎖時(shí),客戶端應(yīng)該設(shè)置一個(gè)網(wǎng)絡(luò)連接和響應(yīng)超時(shí)時(shí)間,這個(gè)超時(shí)時(shí)間應(yīng)該小于鎖的失效時(shí)間。例如你的鎖自動(dòng)失效時(shí)間為10秒,則超時(shí)時(shí)間應(yīng)該在5-50毫秒之間。這樣可以避免服務(wù)器端Redis已經(jīng)掛掉的情況下,客戶端還在死死地等待響應(yīng)結(jié)果。如果服務(wù)器端沒(méi)有在規(guī)定時(shí)間內(nèi)響應(yīng),客戶端應(yīng)該盡快嘗試去另外一個(gè)Redis實(shí)例請(qǐng)求獲取鎖。
客戶端使用當(dāng)前時(shí)間減去開(kāi)始獲取鎖時(shí)間(步驟1記錄的時(shí)間)就得到獲取鎖使用的時(shí)間。
當(dāng)且僅當(dāng)從大多數(shù)( N/2+1 ,這里是3個(gè)節(jié)點(diǎn))的Redis節(jié)點(diǎn)都取到鎖,并且使用的時(shí)間小于鎖失效時(shí)間時(shí),鎖才算獲取成功。
如果取到了鎖,key的真正有效時(shí)間等于有效時(shí)間減去獲取鎖所使用的時(shí)間(步驟3計(jì)算的結(jié)果)。
如果因?yàn)槟承┰?,獲取鎖失?。](méi)有在至少 N/2+1 個(gè)Redis實(shí)例取到鎖或者取鎖時(shí)間已經(jīng)超過(guò)了有效時(shí)間),客戶端應(yīng)該在所有的Redis實(shí)例上進(jìn)行解鎖,這是因?yàn)榧幢隳承㏑edis實(shí)例根本就沒(méi)有加鎖成功,防止某些節(jié)點(diǎn)獲取到鎖但是客戶端沒(méi)有得到響應(yīng)而導(dǎo)致接下來(lái)的一段時(shí)間不能被重新獲取鎖??梢钥吹?,加鎖成功要同時(shí)滿足兩個(gè)條件:
客戶端從超過(guò)半數(shù)(大于等于 N/2+1 )的 Redis 節(jié)點(diǎn)上成功獲取到了鎖;
客戶端從大多數(shù)節(jié)點(diǎn)獲取鎖的總耗時(shí)( t2-t1 )小于鎖設(shè)置的過(guò)期時(shí)間。
簡(jiǎn)單來(lái)說(shuō)就是:如果有超過(guò)半數(shù)的 Redis 節(jié)點(diǎn)成功的獲取到了鎖,并且總耗時(shí)沒(méi)有超過(guò)鎖 的有效時(shí)間,那么就是加鎖成功。
7、Redisson
7.1、簡(jiǎn)單實(shí)現(xiàn)
Redisson 是 Redis 的 Java 客戶端之一,提供了豐富的功能和高級(jí)抽象,包括分布式鎖、分布式集合、分布式對(duì)象等。因此我們能夠很簡(jiǎn)單的通過(guò) Redisson 實(shí)現(xiàn)分布式鎖,而不用自己造輪子。
與此同時(shí),Redisson 是支持原子性加/解鎖、鎖重試、可重入鎖、RedLock 等功能的,感興趣的話可以自行了解。
// 獲取分布式鎖
RLock lock = redissonClient.getLock("myLock");
try {
// 嘗試加鎖,最多等待 10 秒,加鎖后的鎖有效期為 30 秒
boolean locked = lock.tryLock(10, 30, TimeUnit.SECONDS);
if (locked) {
// 成功獲取鎖,執(zhí)行業(yè)務(wù)邏輯
System.out.println("獲取鎖成功,執(zhí)行業(yè)務(wù)邏輯...");
} else {
// 獲取鎖失敗,可能是超時(shí)等待或者其他原因
System.out.println("獲取鎖失敗...");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 釋放鎖
lock.unlock();
// 關(guān)閉 Redisson 客戶端
redissonClient.shutdown();
對(duì)了這里提一嘴,Redisson存儲(chǔ)分布式鎖是通過(guò)Hash結(jié)構(gòu)進(jìn)行存儲(chǔ)的,內(nèi)置的鍵值對(duì)是< 線程標(biāo)識(shí),重入次數(shù)>,其中重入次數(shù)便可用于實(shí)現(xiàn)可重入機(jī)制。
7.2、看門(mén)狗機(jī)制
在 Redisson 中,「看門(mén)狗機(jī)制(Watchdog)」是用于維持 Redis 鍵的過(guò)期時(shí)間的一種機(jī)制。
通常情況下,當(dāng)我們給 Redis 中的鍵設(shè)置過(guò)期時(shí)間后,Redis 會(huì)自動(dòng)管理鍵的生命周期,并在鍵過(guò)期時(shí)通過(guò)過(guò)期刪除策略對(duì)其進(jìn)行處理。然而,如果 Redis 進(jìn)程崩潰或者網(wǎng)絡(luò)故障導(dǎo)致 Redis 服務(wù)器與客戶端連接中斷,那么鍵的過(guò)期時(shí)間可能無(wú)法得到及時(shí)刪除,從而導(dǎo)致鍵仍然存在于 Redis 中。
為了解決這個(gè)問(wèn)題,Redisson 引入了看門(mén)狗機(jī)制。當(dāng) Redisson 客戶端為一個(gè)鍵設(shè)置過(guò)期時(shí) 間時(shí),它會(huì)啟動(dòng)一個(gè)看門(mén)狗線程,該線程會(huì)監(jiān)視鍵的過(guò)期時(shí)間,并在過(guò)期時(shí)間快到期時(shí)自動(dòng)對(duì)鍵進(jìn)行 續(xù)期操作。這樣,即使因?yàn)?Redis 進(jìn)程崩潰或者網(wǎng)絡(luò)故障導(dǎo)致連接中斷,看門(mén)狗仍然可以繼續(xù)維護(hù) 鍵的過(guò)期時(shí)間。
看門(mén)狗機(jī)制的工作原理如下:
當(dāng)客戶端獲取分布式鎖時(shí),Redisson 會(huì)在 Redis 服務(wù)器中創(chuàng)建一個(gè)對(duì)應(yīng)的鍵值對(duì),并給這個(gè)鍵值對(duì)設(shè)置一個(gè)過(guò)期時(shí)間(通常是鎖的持有時(shí)間);
同時(shí),Redisson 會(huì)啟動(dòng)一個(gè)看門(mén)狗線程,在分布式鎖的有效期內(nèi)定時(shí)續(xù)期鎖的過(guò)期時(shí)間;
看門(mén)狗線程會(huì)周期性地檢查客戶端是否還持有鎖,如果持有鎖,則會(huì)為鎖的鍵值對(duì)設(shè)置新的過(guò)期時(shí)間,從而延長(zhǎng)鎖的有效期;
如果客戶端在鎖的有效期內(nèi)未能續(xù)期,即看門(mén)狗線程無(wú)法找到對(duì)應(yīng)的鎖鍵值對(duì),那么鎖會(huì)自動(dòng)過(guò)期,其他客戶端就可以獲取這個(gè)鎖。
在Redisson中,默認(rèn)續(xù)約時(shí)間是30s(可配置),即每隔30s續(xù)約一次,延長(zhǎng)30s。
設(shè)置較短的續(xù)約時(shí)間可以更快地釋放鎖,但可能會(huì)增加續(xù)約的頻率;較長(zhǎng)的續(xù)約時(shí)間可以減 少續(xù)約的次數(shù),但會(huì)使得鎖的有效期更長(zhǎng)。
看門(mén)狗機(jī)制的好處是保證了在獲取分布式鎖后,業(yè)務(wù)邏輯可以在鎖的有效期內(nèi)運(yùn)行,不會(huì)因?yàn)殒i 的過(guò)期而導(dǎo)致鎖失效。當(dāng)業(yè)務(wù)邏輯執(zhí)行時(shí)間超過(guò)鎖的過(guò)期時(shí)間時(shí),看門(mén)狗線程會(huì)自動(dòng)延長(zhǎng)鎖的過(guò)期時(shí) 間,從而避免了鎖的自動(dòng)釋放。
需要注意的是,看門(mén)狗線程是后臺(tái)線程(守護(hù)線程),不會(huì)影響到客戶端的正常業(yè)務(wù)邏輯。同時(shí), 為了避免看門(mén)狗線程過(guò)多占用 Redis 的 CPU 資源,Redisson 會(huì)動(dòng)態(tài)調(diào)整看門(mén)狗的檢查周期,使 得看門(mén)狗線程在不影響性能的情況下維持鎖的有效性
IT架構(gòu)師/技術(shù)大咖的交流圈子,為您提供架構(gòu)體系知識(shí)、技術(shù)文章、流行實(shí)踐案例、解決方案等,行業(yè)大咖分享交流/同行經(jīng)驗(yàn)分享互動(dòng),期待你的加入!掃碼即可加入哦,隨著材料不斷增多社群會(huì)不定期漲價(jià)早加入更優(yōu)惠
免責(zé)聲明:
本公眾號(hào)部分分享的資料來(lái)自網(wǎng)絡(luò)收集和整理,所有文字和圖片版權(quán)歸屬于原作者所有,且僅代表作者個(gè)人觀點(diǎn),與本公眾號(hào)無(wú)關(guān),文章僅供讀者學(xué)習(xí)交流使用,并請(qǐng)自行核實(shí)相關(guān)內(nèi)容,如文章內(nèi)容涉及侵權(quán),請(qǐng)聯(lián)系后臺(tái)管理員刪除。
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.