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