redis续期_面试官:Redis分布式锁如何解决锁超时问题的?
一、前言
關(guān)于redis分布式鎖, 查了很多資料, 發(fā)現(xiàn)很多只是實(shí)現(xiàn)了最基礎(chǔ)的功能, 但是, 并沒(méi)有解決當(dāng)鎖已超時(shí)而業(yè)務(wù)邏輯還未執(zhí)行完的問(wèn)題, 這樣會(huì)導(dǎo)致: A線(xiàn)程超時(shí)時(shí)間設(shè)為10s(為了解決死鎖問(wèn)題), 但代碼執(zhí)行時(shí)間可能需要30s, 然后redis服務(wù)端10s后將鎖刪除, 此時(shí), B線(xiàn)程恰好申請(qǐng)鎖, redis服務(wù)端不存在該鎖, 可以申請(qǐng), 也執(zhí)行了代碼, 那么問(wèn)題來(lái)了, A、B線(xiàn)程都同時(shí)獲取到鎖并執(zhí)行業(yè)務(wù)邏輯, 這與分布式鎖最基本的性質(zhì)相違背: 在任意一個(gè)時(shí)刻, 只有一個(gè)客戶(hù)端持有鎖, 即獨(dú)享
為了解決這個(gè)問(wèn)題, 本文將用完整的代碼和測(cè)試用例進(jìn)行驗(yàn)證, 希望能給小伙伴帶來(lái)一點(diǎn)幫助
二、準(zhǔn)備工作
壓測(cè)工具jmeter
https://pan.baidu.com/share/init?surl=NN0c0tDYQjBTTPA-WTT3yg提取碼: 8f2a
redis-desktop-manager客戶(hù)端
https://pan.baidu.com/share/init?surl=NoJtZZZOXsk45aQYtveWbQ提取碼: 9bhf
postman
https://pan.baidu.com/share/init?surl=28sGJk4zxoOknAd-47hE7w提取碼: vfu7
也可以直接官網(wǎng)下載, 我這邊都整理到網(wǎng)盤(pán)了
需要postman是因?yàn)槲疫€沒(méi)找到j(luò)meter多開(kāi)窗口的辦法, 哈哈
三、說(shuō)明
1、springmvc項(xiàng)目
2、maven依賴(lài)
3、核心類(lèi)
- 分布式鎖工具類(lèi): DistributedLock
- 測(cè)試接口類(lèi): PcInformationServiceImpl
- 鎖延時(shí)守護(hù)線(xiàn)程類(lèi): PostponeTask
四、實(shí)現(xiàn)思路
先測(cè)試在不開(kāi)啟鎖延時(shí)線(xiàn)程的情況下, A線(xiàn)程超時(shí)時(shí)間設(shè)為10s, 執(zhí)行業(yè)務(wù)邏輯時(shí)間設(shè)為30s, 10s后, 調(diào)用接口, 查看是否能夠獲取到鎖, 如果獲取到, 說(shuō)明存在線(xiàn)程安全性問(wèn)題
同上, 在加鎖的同時(shí), 開(kāi)啟鎖延時(shí)線(xiàn)程, 調(diào)用接口, 查看是否能夠獲取到鎖, 如果獲取不到, 說(shuō)明延時(shí)成功, 安全性問(wèn)題解決
五、實(shí)現(xiàn)
1、版本01代碼
1)、DistributedLock
說(shuō)明: 就2個(gè)方法, 加鎖解鎖, 加鎖使用jedis setnx方法, 解鎖執(zhí)行l(wèi)ua腳本, 都是原子性操作
2)、PcInformationServiceImpl
說(shuō)明: 測(cè)試類(lèi)很簡(jiǎn)單, value隨機(jī)生成, 保證唯一, 不會(huì)在超時(shí)情況下解鎖其他客戶(hù)端持有的鎖
3)、打開(kāi)redis-desktop-manager客戶(hù)端, 刷新緩存, 可以看到, 此時(shí)是沒(méi)有add_information_lock的key的
4)、啟動(dòng)jmeter, 調(diào)用接口測(cè)試
設(shè)置5個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn), 在10s的超時(shí)時(shí)間內(nèi)查看redis, add_information_lock存在, 多次調(diào)接口, 只有一個(gè)線(xiàn)程能夠獲取到鎖
往期100篇回顧:一百期面試題匯總
redis
1-4個(gè)請(qǐng)求, 都未獲取到鎖
第5個(gè)請(qǐng)求, 獲取到鎖
OK, 目前為止, 一切正常, 接下來(lái)測(cè)試10s之后, A仍在執(zhí)行業(yè)務(wù)邏輯, 看別的線(xiàn)程是否能獲取到鎖
可以看到, 操作成功, 說(shuō)明A和B同時(shí)執(zhí)行了這段本應(yīng)該獨(dú)享的代碼, 需要優(yōu)化。
往期100篇回顧:一百期面試題匯總
2、版本02代碼
1)、DistributedLock
說(shuō)明: 新增了鎖延時(shí)方法, lua腳本, 自行腦補(bǔ)相關(guān)語(yǔ)法
2)、PcInformationServiceImpl不需要改動(dòng)
3)、PostponeTask
說(shuō)明: 調(diào)用lock同時(shí), 立即開(kāi)啟PostponeTask線(xiàn)程, 線(xiàn)程等待超時(shí)時(shí)間的2/3時(shí)間后, 開(kāi)始執(zhí)行鎖延時(shí)代碼, 如果延時(shí)成功, add_information_lock這個(gè)key會(huì)一直存在于redis服務(wù)端, 直到業(yè)務(wù)邏輯執(zhí)行完畢, 因此在此過(guò)程中, 其他線(xiàn)程無(wú)法獲取到鎖, 也即保證了線(xiàn)程安全性
下面是測(cè)試結(jié)果
10s后, 查看redis服務(wù)端, add_information_lock仍存在, 說(shuō)明延時(shí)成功
此時(shí)用postman再次請(qǐng)求, 發(fā)現(xiàn)獲取不到鎖
看一下控制臺(tái)打印
A線(xiàn)程在19:09:11獲取到鎖, 在10 * 2 / 3 = 6s后進(jìn)行延時(shí), 成功, 保證了業(yè)務(wù)邏輯未執(zhí)行完畢的情況下不會(huì)釋放鎖
A線(xiàn)程執(zhí)行完畢, 鎖釋放, 其他線(xiàn)程又可以競(jìng)爭(zhēng)鎖
OK, 目前為止, 解決了鎖超時(shí)而業(yè)務(wù)邏輯仍在執(zhí)行的鎖沖突問(wèn)題, 還很簡(jiǎn)陋, 而最嚴(yán)謹(jǐn)?shù)姆绞竭€是使用官方的 Redlock 算法實(shí)現(xiàn), 其中 Java 包推薦使用 redisson, 思路差不多其實(shí), 都是在快要超時(shí)時(shí)續(xù)期, 以保證業(yè)務(wù)邏輯未執(zhí)行完畢不會(huì)有其他客戶(hù)端持有鎖
關(guān)于面試面試我還通過(guò)一些渠道整理了需要大廠(chǎng)真實(shí)面試主要有:螞蟻金服、拼多多、阿里云、百度、唯品會(huì)、攜程、豐巢科技、樂(lè)信、軟通動(dòng)力、OPPO、銀盛支付、中國(guó)平安等初,中級(jí),高級(jí)Java面試題集合,附帶超詳細(xì)答案,希望能幫助到大家。
珍藏多年的230個(gè)高端簡(jiǎn)歷模板,也一起送給大家
資料領(lǐng)取步驟
1、關(guān)注,轉(zhuǎn)發(fā)
2、私信發(fā)送:電子書(shū)
總結(jié)
以上是生活随笔為你收集整理的redis续期_面试官:Redis分布式锁如何解决锁超时问题的?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java unsafe park_Jav
- 下一篇: java 弹出软键盘_Android开发