GoLang RabbitMQ TTL與死信隊(duì)列以及延遲隊(duì)列詳細(xì)講解
TTL
TTL 全稱 Time To Live(存活時(shí)間/過(guò)期時(shí)間)。當(dāng)消息到達(dá)存活時(shí)間后,還沒(méi)有被消費(fèi),就會(huì)被自動(dòng)清除。RabbitMQ可以設(shè)置兩種過(guò)期時(shí)間:
- 對(duì)消息設(shè)置過(guò)期時(shí)間。
- 對(duì)整個(gè)隊(duì)列(Queue)設(shè)置過(guò)期時(shí)間。
如何設(shè)置
- 設(shè)置隊(duì)列過(guò)期時(shí)間使用參數(shù):
x-message-ttl
,單位:ms(毫秒),會(huì)對(duì)整個(gè)隊(duì)列消息統(tǒng)一過(guò)期。 - 設(shè)置消息過(guò)期時(shí)間使用參數(shù):
expiration
,單位:ms(毫秒),當(dāng)該消息在隊(duì)列頭部時(shí)(消費(fèi)時(shí)),會(huì)單獨(dú)判斷這一消息是否過(guò)期。
如果兩者都設(shè)置了過(guò)期時(shí)間,以時(shí)間短的為準(zhǔn)。
在streadway/amqp庫(kù)提供的API中設(shè)置TTL
設(shè)置隊(duì)列過(guò)期時(shí)間:
QueueDeclare
函數(shù)的最后一個(gè)參數(shù)是一個(gè)amqp.Table
類型,它的聲明是這樣的: type Table map[string]interface{}
,其實(shí)是一個(gè)可以用于設(shè)置隊(duì)列屬性的map。
// 設(shè)置Queue ttl為5s args := amqp.Table{"x-message-ttl": 5000} q, e := ch.QueueDeclare( name, //隊(duì)列名 false, true, false, false, args, //設(shè)置Queue ttl為5s )
設(shè)置消息過(guò)期時(shí)間:
e = q.channel.Publish( "", queue, false, false, amqp.Publishing{ // 設(shè)置當(dāng)前發(fā)送消息的過(guò)期時(shí)間為3s Expiration: "3000", ReplyTo: q.Name, Body: []byte(str), })
死信隊(duì)列
當(dāng)一個(gè)隊(duì)列中存在死信
時(shí),RabbitMQ會(huì)把消息發(fā)送給DLX
(死信交換機(jī)),進(jìn)而被路由到另一個(gè)隊(duì)列中,這個(gè)隊(duì)列就叫做死信隊(duì)列。
死信就是指沒(méi)有被消費(fèi)者消費(fèi)成功的消息,一條消息變成死信有三種情況:
- 如果給消息隊(duì)列設(shè)置了最大容量
x-max-length
,隊(duì)列已經(jīng)滿了,后續(xù)再進(jìn)來(lái)的消息會(huì)溢出,無(wú)法被隊(duì)列接收就會(huì)變成死信。 - 消息接收時(shí)被拒絕會(huì)變成死信,例如調(diào)用
Reject()
函數(shù),并設(shè)置requeue
為false
。 - 如果給消息隊(duì)列設(shè)置了消息的過(guò)期時(shí)間
x-message-ttl
,或者發(fā)送消息時(shí)設(shè)置了當(dāng)前消息的過(guò)期時(shí)間,當(dāng)消息在隊(duì)列中的存活時(shí)間大于過(guò)期時(shí)間時(shí),就會(huì)變成死信。
如何將死信發(fā)送給DLX
為隊(duì)列設(shè)置參數(shù)即可,將要發(fā)送死信的隊(duì)列配置以下兩個(gè)參數(shù):
x-dead-letter-exchange: [DLX的名字]
x-dead-letter-routing-key: [DLX的routing key]
下面是死信隊(duì)列的工作流程:
延遲隊(duì)列
延時(shí)隊(duì)列就是用來(lái)存放需要在指定時(shí)間被處理的元素的隊(duì)列,通常可以用來(lái)處理一些具有過(guò)期性操作的業(yè)務(wù)。
比如十分鐘內(nèi)未支付則取消訂單,原先這個(gè)功能我們可以使用定時(shí)器來(lái)實(shí)現(xiàn),即每隔一段時(shí)間去數(shù)據(jù)庫(kù)對(duì)比未支付訂單的當(dāng)前時(shí)間與訂單創(chuàng)建時(shí)間。但是定時(shí)器的時(shí)長(zhǎng)難以確定,太長(zhǎng)會(huì)導(dǎo)致訂單失效時(shí)間出現(xiàn)誤差,太短則會(huì)增大數(shù)據(jù)庫(kù)壓力。
實(shí)現(xiàn)
在RabbitMQ中沒(méi)有提供延遲隊(duì)列的功能,但是我們可以使用:TTL+死信隊(duì)列組合的方式來(lái)實(shí)現(xiàn)延遲隊(duì)列的效果。
下面是實(shí)現(xiàn)延遲隊(duì)列的流程圖:
Go實(shí)現(xiàn)延遲隊(duì)列
創(chuàng)建一個(gè)死信交換機(jī)
再創(chuàng)建一個(gè)死信隊(duì)列
將死信隊(duì)列綁定至死信交換機(jī)
創(chuàng)建一個(gè)正常隊(duì)列,并指定消息過(guò)期后被發(fā)往的死信交換機(jī)
生產(chǎn)者
func main() { conn, _ := amqp.Dial("amqp://guest:guest@35.76.111.125:5672/") ch, _ := conn.Channel() body := "This is a delayed message, created at " + time.Now().Format("2006-01-02 15:04:05") fmt.Println(body) // 發(fā)送消息到queue.normal隊(duì)列中 ch.Publish("", "queue.normal", false, false, amqp.Publishing{ Body: []byte(body), Expiration: "10000", // 設(shè)置TTL為10秒 }) defer conn.Close() defer ch.Close() }
消費(fèi)者
func main() { conn, _ := amqp.Dial("amqp://guest:guest@35.76.111.125:5672/") ch, _ := conn.Channel() //監(jiān)聽(tīng)queue.dlx隊(duì)列 msgs, _ := ch.Consume( "queue.dlx", "", true, false, false, false, nil, ) for d := range msgs { fmt.Printf("receive: %s\n", d.Body) // 收到消息,業(yè)務(wù)處理 } }
流程說(shuō)明
生產(chǎn)者生產(chǎn)一條消息,然后指定消息的TTL為10s,接著將消息發(fā)給普通隊(duì)列,消息在普通隊(duì)列中過(guò)期后被發(fā)往死信交換機(jī),死信交換機(jī)將這條消息路由給延遲隊(duì)列。消費(fèi)者一直在監(jiān)聽(tīng)到延遲隊(duì)列中的死信后,開(kāi)始消費(fèi)。
到此這篇關(guān)于GoLang RabbitMQ TTL與死信隊(duì)列以及延遲隊(duì)列詳細(xì)講解的文章就介紹到這了,更多相關(guān)GoLang RabbitMQ內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang使用cobra實(shí)現(xiàn)命令行程序的示例代碼
Cobra 是 Go 語(yǔ)言中一個(gè)強(qiáng)大的命令行應(yīng)用庫(kù),它提供了創(chuàng)建命令行工具所需的基本結(jié)構(gòu)和功能,被許多開(kāi)發(fā)者用于構(gòu)建各種命令行工具和應(yīng)用程序,本文將給大家介紹Golang使用cobra實(shí)現(xiàn)命令行程序,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02GoLang中生成UUID唯一標(biāo)識(shí)的實(shí)現(xiàn)方法
UUID是讓分散式系統(tǒng)中的所有元素,都能有唯一的辨識(shí)信息,本文主要介紹了GoLang中生成UUID唯一標(biāo)識(shí)的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-08-08詳解Go多協(xié)程并發(fā)環(huán)境下的錯(cuò)誤處理
這篇文章主要介紹了詳解Go多協(xié)程并發(fā)環(huán)境下的錯(cuò)誤處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08使用Golang快速構(gòu)建出命令行應(yīng)用程序
在日常開(kāi)發(fā)中,大家對(duì)命令行工具(CLI)想必特別熟悉了,如果說(shuō)你不知道命令工具,那你可能是個(gè)假開(kāi)發(fā)。每天都會(huì)使用大量的命令行工具,例如最常用的Git、Go、Docker等,這篇文章主要介紹了使用Golang快速構(gòu)建出命令行應(yīng)用程序,需要的朋友可以參考下2023-02-02基于Golang實(shí)現(xiàn)延遲隊(duì)列(DelayQueue)
延遲隊(duì)列是一種特殊的隊(duì)列,元素入隊(duì)時(shí)需要指定到期時(shí)間(或延遲時(shí)間),從隊(duì)頭出隊(duì)的元素必須是已經(jīng)到期的。本文將用Golang實(shí)現(xiàn)延遲隊(duì)列,感興趣的可以了解下2022-09-09golang 實(shí)現(xiàn)比特幣內(nèi)核之處理橢圓曲線中的天文數(shù)字
比特幣密碼學(xué)中涉及到的大數(shù)運(yùn)算超出常規(guī)整數(shù)范圍,需使用golang的big包進(jìn)行處理,通過(guò)使用big.Int類型,能有效避免整數(shù)溢出,并保持邏輯正確性,測(cè)試展示了在不同質(zhì)數(shù)模下的運(yùn)算結(jié)果,驗(yàn)證了邏輯的準(zhǔn)確性,此外,探討了費(fèi)馬小定理在有限字段除法運(yùn)算中的應(yīng)用2024-11-11