在高并發(fā)環(huán)境下,如何保證集群中只有一個(gè)腳本線程運(yùn)行并實(shí)時(shí)監(jiān)控其狀態(tài),是系統(tǒng)穩(wěn)定性的關(guān)鍵。本文針對(duì)集群腳本線程唯一性和運(yùn)行狀態(tài)監(jiān)控問(wèn)題,提出一種基于redisson分布式鎖的解決方案,有效解決了傳統(tǒng)方案的不足。
場(chǎng)景:一個(gè)出庫(kù)任務(wù),允許多個(gè)用戶控制啟動(dòng)和停止。只要至少一個(gè)用戶開(kāi)啟,任務(wù)持續(xù)執(zhí)行;所有用戶關(guān)閉后,任務(wù)停止。系統(tǒng)采用兩臺(tái)后端服務(wù)器負(fù)載均衡,使用redis進(jìn)行狀態(tài)管理。原方案存在線程中斷難以恢復(fù),用戶無(wú)法實(shí)時(shí)感知腳本運(yùn)行狀態(tài)等問(wèn)題。
原方案利用Redis key值判斷任務(wù)狀態(tài),采用死循環(huán)線程執(zhí)行任務(wù),存在單點(diǎn)故障和監(jiān)控不便等缺陷。線程中斷后需要手動(dòng)干預(yù)恢復(fù)。
改進(jìn)方案:采用Redisson分布式鎖。Redisson是基于Redis的Java客戶端,其分布式鎖機(jī)制能有效解決集群環(huán)境下的資源競(jìng)爭(zhēng)。Redisson分布式鎖具備自動(dòng)續(xù)期和過(guò)期機(jī)制,確保高可用性。
當(dāng)服務(wù)獲取到鎖后,啟動(dòng)出庫(kù)腳本線程。鎖的過(guò)期時(shí)間和續(xù)期時(shí)間可配置,即使服務(wù)崩潰,鎖也會(huì)在一段時(shí)間后自動(dòng)釋放,其他服務(wù)可重新獲取鎖并啟動(dòng)任務(wù),保證任務(wù)的唯一性和高可用性。
鎖的存在與否直接反映腳本運(yùn)行狀態(tài):鎖存在,任務(wù)運(yùn)行;鎖不存在,任務(wù)停止或未啟動(dòng)。用戶可通過(guò)查詢鎖狀態(tài)實(shí)時(shí)監(jiān)控腳本運(yùn)行情況,比之前的Redis key狀態(tài)判斷更可靠高效。
具體流程:
- 服務(wù)啟動(dòng)后嘗試獲取Redisson分布式鎖。
- 獲取到鎖的服務(wù)啟動(dòng)出庫(kù)腳本線程,執(zhí)行出庫(kù)任務(wù)。
- Redisson自動(dòng)續(xù)期鎖。
- 任務(wù)執(zhí)行完畢,釋放Redisson分布式鎖。
- 客戶端檢查Redisson分布式鎖是否存在,判斷任務(wù)運(yùn)行狀態(tài)。
此方案解決了單點(diǎn)故障、監(jiān)控不便和線程中斷難以恢復(fù)的問(wèn)題,提升了系統(tǒng)可靠性和可維護(hù)性,用戶可清晰了解腳本運(yùn)行狀態(tài),避免因線程中斷導(dǎo)致的任務(wù)停滯。