偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

自省:分布式鎖主動(dòng)續(xù)期的入門級(jí)實(shí)現(xiàn)

開發(fā) 項(xiàng)目管理
如果某個(gè)客戶端獲得鎖之后處理時(shí)間超過最大約定時(shí)間,或者持鎖期間內(nèi)發(fā)生了故障導(dǎo)致無法主動(dòng)釋放鎖,其持有的鎖也能夠被其他機(jī)制正確釋放,并保證后續(xù)其它客戶端也能加鎖,整個(gè)處理流程繼續(xù)正常執(zhí)行。

?一、背景

在《??# 分布式鎖上-初探??》中有提到一個(gè)分布式鎖應(yīng)具備的功能特點(diǎn)中有避免死鎖這一條:

如果某個(gè)客戶端獲得鎖之后處理時(shí)間超過最大約定時(shí)間,或者持鎖期間內(nèi)發(fā)生了故障導(dǎo)致無法主動(dòng)釋放鎖,其持有的鎖也能夠被其他機(jī)制正確釋放,并保證后續(xù)其它客戶端也能加鎖,整個(gè)處理流程繼續(xù)正常執(zhí)行。

簡(jiǎn)單解釋一下:

  1. 客戶端搶到分布式鎖之后開始執(zhí)行任務(wù),執(zhí)行完畢后再釋放分布式鎖。
  2. 持鎖后因客戶端異常未能把鎖釋放,會(huì)導(dǎo)致鎖成為永恒鎖。
  3. 為了避免這種情況,在創(chuàng)建鎖的時(shí)候給鎖指定一個(gè)過期時(shí)間。
  4. 到期之后鎖會(huì)被自動(dòng)刪除掉,這個(gè)角度看是對(duì)鎖資源的一種保護(hù)。

二、理還亂?

邏輯看很簡(jiǎn)單,也很清晰,但任何事情都有兩面性,自動(dòng)刪除自然有理,但肯定也有弊端。如果要把鎖的功能做的健壯,總要從不斷地自我質(zhì)疑、自我反思中,理順?biāo)悸?,尋找答案,我認(rèn)為這屬于自省式學(xué)習(xí),以后也想嘗試這種模式,一起來試試吧:

  • 問題:鎖過期了會(huì)被刪掉,可是任務(wù)沒結(jié)束怎么辦?如果鎖被釋放的時(shí)候,任務(wù)尚未執(zhí)行完畢,那就可能導(dǎo)致其它客戶端又搶到鎖,任務(wù)被重復(fù)執(zhí)行。
  • 問題:把鎖的過期時(shí)間定得長一點(diǎn)?邏輯聽起來沒錯(cuò),如果你能確定任務(wù)的最大耗時(shí),那沒問題;大部分情況都很難確定任務(wù)的最大耗時(shí)該是多少。
  • 問題:鎖的過期時(shí)間定多長合適?反正會(huì)被釋放,過期時(shí)間定的足夠長吧;如果鎖使用的頻率很高,加了鎖程序有bug釋放不掉,服務(wù)端豈不是要出現(xiàn)大量的垃圾數(shù)據(jù)?思來想去,對(duì)一個(gè)健壯的分布式鎖來說,過期時(shí)間設(shè)置太長了不合適,設(shè)置太短了也不合適。
  • 問題:怎么平衡?不長不短,主動(dòng)延期!持鎖期間,酌情推后鎖的過期時(shí)間,以基于Redis的分布式鎖來說,就需要調(diào)用 API 重置鎖 key 的過期時(shí)間。當(dāng)前線程持鎖后在執(zhí)行任務(wù)期間不能再調(diào)用 API 重試鎖 key 的過期時(shí)間。
  • 問題:誰來調(diào)用API呢?需要使用其他的線程來執(zhí)行續(xù)期。
  • 問題:給每個(gè)鎖配一個(gè)線程?可以,如果使用分布式鎖的場(chǎng)景中沒有什么并發(fā),一個(gè)客戶端也就那么三兩個(gè)鎖同時(shí)存在,那就沒問題。每個(gè)鎖搶鎖成功后,開啟一個(gè)線程,在線程中通過循環(huán)給鎖續(xù)期。
public void run() {
while (true) {
// 續(xù)租
action.run();
}
}
  • 問題:多久執(zhí)行一次續(xù)期?有一些常規(guī)處理是續(xù)租間隔默認(rèn)采用過期時(shí)間的1/3。若把鎖的過期時(shí)間設(shè)定為與實(shí)際耗時(shí)相差不大,這樣通過一兩次續(xù)租基本就滿足了大部分的情況。
  • 問題:為什么要觸發(fā)一次續(xù)期操作呢,這不浪費(fèi)資源嗎?采用過期時(shí)間1/3間隔,若用戶定義鎖3秒過期,那每秒鐘都有一個(gè)續(xù)期指令,有沒有覺得也不太合適。
  • 問題:要不要避免續(xù)期指令太頻繁?避免續(xù)期指令太頻繁調(diào)用是有必要的,也可以增加一個(gè)續(xù)期的最小間隔時(shí)間,比如最少是5秒。可由用戶自己控制續(xù)期周期,沒必要一定要發(fā)起續(xù)期調(diào)用。比如任務(wù)執(zhí)行大多在5秒鐘,那么就把鎖定為7秒,續(xù)期時(shí)間定在6秒,那么6秒內(nèi)任務(wù)結(jié)束了就不用續(xù)期,即不必把過期時(shí)間定的太長,也不必執(zhí)行一兩次續(xù)期操作。
  • 問題:續(xù)租的間隔怎么實(shí)現(xiàn)?線程內(nèi)間隔控制通常是通過 sleep() 方法,稍微精準(zhǔn)一點(diǎn)的話,單位使用毫秒。
public void run() {
while (true) {
// 1、間隔
TimeUnit.MILLISECONDS.sleep(sleepTime);
// 2、續(xù)租
action.run();
}
}
  • 問題:線程要關(guān)閉吧?釋放鎖的時(shí)候要主動(dòng)關(guān)閉負(fù)責(zé)續(xù)期的線程,所以線程的循環(huán)里要有一個(gè)變量來控制退出 while 循環(huán)
public void run() {
while (isRunning) {
// 1、間隔
TimeUnit.MILLISECONDS.sleep(sleepTime);
// 2、續(xù)租
action.run();
}
}
  • 問題:變量是跨線程訪問,如何保證跨線程的可見性呢?在變量上增加 volatile 關(guān)鍵字。
private volatile boolean isRunning = true;

void cancel(){
//控制線程退出
this.isRunning = true;
}
  • 問題:如果續(xù)期線程里在 sleep(),那就一直等 sleep() 結(jié)束?如果等到 sleep() 結(jié)束,就挺浪費(fèi)資源的
  • 問題:能不能快速結(jié)束 sleep() 狀態(tài)?可以,通過 interrupt(),需留意,被打斷的時(shí)候會(huì)拋異常 InterruptedException
void cancel(){
//控制線程退出
this.isRunning = true;
//中斷線程
this.interrupt();
}

到這里,似乎都理順了。

三、新的思考

  • 問題:如果同時(shí)有成百上千個(gè)鎖呢?同時(shí)有成百上千個(gè)線程在工作,你若認(rèn)為沒問題,不存在,那ok,不用繼續(xù)看下一篇。
  • 那怎么辦呢?可以用 Executors.newScheduledThreadPool ,里邊有 scheduleAtFixedRate

  • 阿里 Java 代碼規(guī)范不允許用Execurots嘛?
  • 圖片

    • 不能用?風(fēng)險(xiǎn)是什么?

    本文轉(zhuǎn)載自微信公眾號(hào)「架構(gòu)染色」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系【架構(gòu)染色】公眾號(hào)作者。

    責(zé)任編輯:武曉燕 來源: 架構(gòu)染色
    相關(guān)推薦

    2024-11-28 15:11:28

    2019-06-19 15:40:06

    分布式鎖RedisJava

    2021-02-28 07:49:28

    Zookeeper分布式

    2018-04-03 16:24:34

    分布式方式

    2017-01-16 14:13:37

    分布式數(shù)據(jù)庫

    2017-04-13 10:51:09

    Consul分布式

    2022-04-08 08:27:08

    分布式鎖系統(tǒng)

    2025-03-31 09:59:11

    2019-02-26 09:51:52

    分布式鎖RedisZookeeper

    2022-01-06 10:58:07

    Redis數(shù)據(jù)分布式鎖

    2023-08-21 19:10:34

    Redis分布式

    2021-10-25 10:21:59

    ZK分布式鎖ZooKeeper

    2024-10-09 17:12:34

    2018-04-09 09:15:32

    數(shù)據(jù)庫DB分布式鎖

    2023-03-01 08:07:51

    2022-10-27 10:44:14

    分布式Zookeeper

    2023-09-13 09:52:14

    分布式鎖Java

    2024-07-29 09:57:47

    2024-10-07 10:07:31

    2024-04-01 05:10:00

    Redis數(shù)據(jù)庫分布式鎖
    點(diǎn)贊
    收藏

    51CTO技術(shù)棧公眾號(hào)