新聞中心
??Redis隊(duì)列分布式技術(shù)已被廣泛應(yīng)用于各種業(yè)務(wù)場(chǎng)景,但是使用Entity Framework時(shí),它有一個(gè)常見(jiàn)的問(wèn)題:重復(fù)消費(fèi)。多個(gè)客戶(hù)端將同一條消息從消息隊(duì)列中分發(fā)出去,但有時(shí)候只有一個(gè)客戶(hù)端可以消費(fèi)消息,從而導(dǎo)致重復(fù)消費(fèi)的問(wèn)題。因此,怎樣避免Redis隊(duì)列中的重復(fù)消費(fèi)是運(yùn)維人員和開(kāi)發(fā)人員面臨的一個(gè)有趣的問(wèn)題。

??首先,對(duì)于一個(gè)單個(gè)消息,提供一個(gè)消息編號(hào),每個(gè)消息在分發(fā)之前,都 應(yīng)該被賦予一個(gè)唯一的值,當(dāng)消費(fèi)者從Redis中收取消息時(shí),可以設(shè)置一個(gè)KEY來(lái)標(biāo)識(shí)當(dāng)前消息,這樣做可以讓微服務(wù)可以安全地運(yùn)行,同時(shí)又能保證消息不會(huì)被重復(fù)消費(fèi)。代碼如下:
public Task publish(string message)
{
//獲取消息編號(hào)
int messageId = GetMessageId();
//將消息封裝成一個(gè)帶有消息編號(hào)的完整消息
Message message = new Message(){
messageId = messageId,
content = message;
}
//將消息發(fā)布到Redis
awt _redis.EnqueueAsync(key,message);
return Task.CompletedTask;
}
??其次,實(shí)現(xiàn)一個(gè)函數(shù)來(lái)保證發(fā)布消息時(shí)完整性:在寫(xiě)入Redis之前,先檢查到底當(dāng)前消息是否已被發(fā)布,也就是說(shuō)在將消息發(fā)送給多個(gè)客戶(hù)端之前,通過(guò)一些并發(fā)算法和技術(shù)去檢查是否存在消息編號(hào)相同的消息,只有數(shù)據(jù)校驗(yàn)通過(guò)之后,才將消息寫(xiě)入Redis。代碼如下:
public Task publish(string message)
{
int messageId = GetMessageId();
string key = "message:" + messageId;
//把任務(wù)放入緩存中
if(!awt _redis.StringSetAsync(key, message))
{
//緩存中的消息和要發(fā)布的消息不一致。
//將消息放回原隊(duì)列
awt _redis.EnqueueAsync(message);
return;
}
Message message = new Message(){
messageId = messageId,
content = message;
}
//將消息發(fā)布到Redis
awt _redis.EnqueueAsync(key,message);
return Task.CompletedTask;
}
??最后,提供一個(gè)隊(duì)列標(biāo)記機(jī)制,如果有消費(fèi)者發(fā)現(xiàn)消息正在被處理,則可以立刻移除消息,從而避免重復(fù)消費(fèi)。例如我們可以在發(fā)布消息前,使用如下代碼標(biāo)記當(dāng)前消息:
//設(shè)置一個(gè)key表示當(dāng)前消息的消費(fèi)是否結(jié)束
string key = "inprogress:" + messageId;
//每次訂閱該消息之前,使用iflock()方法防止重復(fù)消費(fèi)
bool lockResutl = awt _redis.IfLockAsync(key);
if(lockResutl == false)
{
//table 表示當(dāng)前消息在處理的過(guò)程中,已經(jīng)被別人消費(fèi)了,因此從隊(duì)列中移除
awt _redis.DequeueAsync(message);
return;
}
??總之,要想避免Redis隊(duì)列中出現(xiàn)重復(fù)消費(fèi)的問(wèn)題,就必須要做到三點(diǎn):首先提供消息編號(hào),其次實(shí)現(xiàn)消息寫(xiě)入之前的數(shù)據(jù)完整性校驗(yàn),最后提供隊(duì)列標(biāo)記機(jī)制。
成都創(chuàng)新互聯(lián)科技有限公司,是一家專(zhuān)注于互聯(lián)網(wǎng)、IDC服務(wù)、應(yīng)用軟件開(kāi)發(fā)、網(wǎng)站建設(shè)推廣的公司,為客戶(hù)提供互聯(lián)網(wǎng)基礎(chǔ)服務(wù)!
創(chuàng)新互聯(lián)(www.cdcxhl.com)提供簡(jiǎn)單好用,價(jià)格厚道的香港/美國(guó)云服務(wù)器和獨(dú)立服務(wù)器。創(chuàng)新互聯(lián)成都老牌IDC服務(wù)商,專(zhuān)注四川成都IDC機(jī)房服務(wù)器托管/機(jī)柜租用。為您精選優(yōu)質(zhì)idc數(shù)據(jù)中心機(jī)房租用、服務(wù)器托管、機(jī)柜租賃、大帶寬租用,可選線路電信、移動(dòng)、聯(lián)通等。
網(wǎng)站欄目:如何避免Redis隊(duì)列中的重復(fù)消費(fèi)(redis隊(duì)列重復(fù)消費(fèi))
文章起源:http://fisionsoft.com.cn/article/cdhoidh.html
其他資訊
- ci連接數(shù)據(jù)庫(kù)_數(shù)據(jù)發(fā)布CI/CD、任務(wù)運(yùn)維
- Redis配置激發(fā)性能的秘訣(redis配置性能優(yōu)化)
- 帝國(guó)cms簡(jiǎn)介標(biāo)簽是什么
- 我家的是電信,現(xiàn)在電視可以連接網(wǎng)絡(luò)電視,電腦連接不上網(wǎng),打開(kāi)網(wǎng)頁(yè)上面顯示無(wú)法解析服務(wù)器DNS地址?(這個(gè)解析正常但還是打不開(kāi)網(wǎng)頁(yè))
- 什么是網(wǎng)速,什么是帶寬,什么是下載速度?網(wǎng)速與下載速度的關(guān)系?服務(wù)器帶寬與速度


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