最近往服務(wù)的消息推送上加了一個(gè)分布式的鎖倒戏,用來防止短時(shí)間內(nèi)相同消息重復(fù)處理的情況对扶,思路是用redis的setnx 設(shè)置一個(gè)key(key值根據(jù)業(yè)務(wù)制定见秽,需要唯一)郁副,然后設(shè)置key的超時(shí)時(shí)間為5分鐘锣夹,用于防止系統(tǒng)異常時(shí)沒有主動釋放鎖的防御页徐,在線上灰度環(huán)境試運(yùn)行后,發(fā)現(xiàn)兩個(gè)問題银萍,一個(gè)是程序沒有主動釋放鎖变勇,另一個(gè)是redis沒有刪除超時(shí)過期的key,導(dǎo)致key值一直存在贴唇,后續(xù)的操作一直被排斥搀绣。
經(jīng)調(diào)查發(fā)現(xiàn),第一個(gè)問題戳气,程序沒有主動釋放key值链患,是因?yàn)閗ey值有一部分引用了業(yè)務(wù)消息的狀態(tài),即格式為:systemA-cluster-lock-業(yè)務(wù)id-status-action瓶您,其中status在處理前后發(fā)生了變化導(dǎo)致沒能刪除原來的key麻捻,做法是通過copy多一份key值保留纲仍;
第二個(gè)問題:redis沒有刪除超時(shí)過期的key,通過ttl key命令查看贸毕,return 0巷折,通過查看官方文檔https://redis.io/commands/ttl,redis的ttl返回的是剩余過期時(shí)間崖咨,當(dāng)key不存在時(shí)返回-2锻拘,即沒有返回0的情況。繼續(xù)折騰击蹲,終于在https://blog.csdn.net/alexhendar/article/details/50857176 這邊博客中找到了答案署拟,原來和redis的配置有關(guān),當(dāng)redis為slave且read_only關(guān)閉時(shí)歌豺,redis不會刪除過期的key值推穷,此時(shí)ttl key返回0,通過查看redis配置类咧,果然如此馒铃,于是修改redis配置,第二個(gè)問題得解痕惋。