新聞中心
在使用Redis隊(duì)列作為消息隊(duì)列時(shí),由于同一條消息可能會(huì)被多次投入隊(duì)列,如果沒(méi)有有效的限制,就會(huì)導(dǎo)致消息的重復(fù)執(zhí)行,這是在開(kāi)發(fā)過(guò)程中必須要解決的問(wèn)題。解決重復(fù)消息執(zhí)行的一種方法是采用冪等。我們可以為每一條入隊(duì)消息生成一個(gè)唯一標(biāo)識(shí),并將這個(gè)標(biāo)識(shí)存在Redis中,當(dāng)消息被消費(fèi)時(shí),如果該標(biāo)識(shí)已經(jīng)存在,則視為重復(fù)消息,不做任何處理。

下面以PHP語(yǔ)言為例,給出一個(gè)具體的解決方案。
在發(fā)布消息時(shí),消息內(nèi)容里增加messageId值,messageID可以使用uuid或者消息發(fā)出的時(shí)間戳(如果消息發(fā)出的時(shí)間不會(huì)重復(fù))等來(lái)標(biāo)識(shí)。
在消費(fèi)消息時(shí),先讀取messageID值,然后將messageID值設(shè)置到一個(gè)redis鍵,當(dāng)消費(fèi)下一個(gè)消息時(shí),先讀取messageID,查詢(xún)?cè)撴I是否存在,如果存在,則認(rèn)為是重復(fù)消息,則忽略消費(fèi)。
下面是該實(shí)現(xiàn)方案的代碼:
$msg = $redis->rPop();
// 讀取消息的messageID
$msgID = $msg['messageID'];
// 使用messageID設(shè)置redis鍵
$key = "lQueue:" . $msgID;
// 查詢(xún)?cè)撴I是否存在
if($redis->exists($key)){
// 如果存在,則忽略處理
return;
}else{
// 設(shè)置該鍵,5分鐘過(guò)期
$redis->set($key,1, array('EX',300));
// 處理消息內(nèi)容
......
}
以上是解決Redis隊(duì)列重復(fù)執(zhí)行問(wèn)題的一種有效解決方案,它采用在消息入隊(duì)時(shí)使用唯一標(biāo)識(shí)messageID,在取出時(shí),使用對(duì)應(yīng)的messageID去驗(yàn)證,可有效避免同一條消息重復(fù)投入隊(duì)列和重復(fù)執(zhí)行的問(wèn)題。此外,在實(shí)際應(yīng)用過(guò)程中,也可以根據(jù)實(shí)際的使用情況,進(jìn)行自己的定制,保證更加可靠的消息隊(duì)列服務(wù)。
成都創(chuàng)新互聯(lián)科技有限公司,經(jīng)過(guò)多年的不懈努力,公司現(xiàn)已經(jīng)成為一家專(zhuān)業(yè)從事IT產(chǎn)品開(kāi)發(fā)和營(yíng)銷(xiāo)公司。廣泛應(yīng)用于計(jì)算機(jī)網(wǎng)絡(luò)、設(shè)計(jì)、SEO優(yōu)化、關(guān)鍵詞排名等多種行業(yè)!
當(dāng)前名稱(chēng):解決Redis隊(duì)列重復(fù)執(zhí)行問(wèn)題(redis隊(duì)列重復(fù)執(zhí)行)
文章地址:http://fisionsoft.com.cn/article/ccooegs.html


咨詢(xún)
建站咨詢(xún)
