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

