背景介紹:
筆者最近研究了下rabbitmq碳抄,便很好奇它是怎么保證不丟失消息的呢犁苏?于是便整理了這篇文章來跟大家分享下,自己的理解聂儒,如有不準確的地方或者不同的意見虎锚,還請各位能夠給出反饋,我們可以討論衩婚,相互學習窜护,相互成長。
基礎(chǔ)知識:
在開始探討這個問題之前非春,筆者還是覺得很有必要將rabbitmq的架構(gòu)等基礎(chǔ)知識回顧下柱徙,如下所示:
對于使用rabbitmq的服務(wù)來說,主要由三部分構(gòu)成奇昙,它們分別是:生產(chǎn)者护侮,rabbitmq,消費者储耐。這三者之間是通過網(wǎng)絡(luò)來進行通訊的羊初,其中與生產(chǎn)者對應(yīng)的是exchange,與消費者對應(yīng)的是connection什湘,而rabbitmq內(nèi)部又由exchange长赞,queue晦攒,connection三部分構(gòu)成。
消息的流程:消息是由生產(chǎn)者生產(chǎn)了之后得哆,上報給exchange勤家,exchange綁定并存儲到queue中,再傳遞給最終的消費者手里柳恐。
如此以來,整個過程就分成了三大場景:
場景1: 生產(chǎn)者與exchange的上報消息热幔,如何保證不丟失乐设?
對于網(wǎng)絡(luò)通訊來說,解決丟數(shù)據(jù)最好的辦法就是绎巨,消息確認機制近尚,而rabbitmq里面是通過兩個方式來保證:一種是事務(wù)機制,這個是在amqp協(xié)議層面保證的场勤,具體操作如下所示:
RabbitMQ中與事務(wù)機制有關(guān)的方法有三個:txSelect(), txCommit()以及txRollback(), txSelect用于將當前channel設(shè)置成transaction模式戈锻,txCommit用于提交事務(wù),txRollback用于回滾事務(wù)和媳,在通過txSelect開啟事務(wù)之后格遭,我們便可以發(fā)布消息給broker代理服務(wù)器了,如果txCommit提交成功了留瞳,則消息一定到達了broker了拒迅,如果在txCommit執(zhí)行之前broker異常崩潰或者由于其他原因拋出異常,這個時候我們便可以捕獲異常通過txRollback回滾事務(wù)了她倘。(備注:采用事務(wù)機制實現(xiàn)會降低RabbitMQ的消息吞吐量璧微。)
步驟為:
1.client----發(fā)送----->Tx.Select
2.broker----發(fā)送----->Tx.Select-Ok(之后publish)
3.client------發(fā)送----->Tx.Commit
4.broker------發(fā)送---->Tx.Commit-Ok
一種是confrim機制:
原理:消息響應(yīng)機制,
生產(chǎn)者將信道設(shè)置成confirm模式硬梁,一旦信道進入confirm模式前硫,所有在該信道上面發(fā)布的消息都會被指派一個唯一的ID(從1開始),一旦消息被投遞到所有匹配的隊列之后荧止,broker就會發(fā)送一個確認給生產(chǎn)者(包含消息的唯一ID),這就使得生產(chǎn)者知道消息已經(jīng)正確到達目的隊列了屹电,如果消息和隊列是可持久化的,那么確認消息會將消息寫入磁盤之后發(fā)出罩息,broker回傳給生產(chǎn)者的確認消息中deliver-tag域包含了確認消息的序列號嗤详。
confrim的優(yōu)勢是,它是異步的瓷炮,在生產(chǎn)者發(fā)送完一個消息之后葱色,不必要等這個消息的返回,就可以繼續(xù)處理另外一個消息娘香,等待消息的ack返回之后苍狰,再去處理前面發(fā)過的消息办龄,類似于多路復用的做法。rabbitmq在收到之后淋昭,會回復ack俐填,如果因為rabbitmq自身的問題導致的,會回復nack消息翔忽。
對于生產(chǎn)者來說英融,為了方便確認消息有沒有真正到達rabbitmq端,還需要在生產(chǎn)者端設(shè)置超時重發(fā)歇式,畢竟網(wǎng)絡(luò)里面是可能丟失消息的驶悟。
confrim方式使用的API:
https://godoc.org/github.com/streadway/amqp#Channel.Confirm
場景2: 消費者從queue中獲取消息如何保證不丟失?
........
詳細參考:灰子學技術(shù) :Rabbitmq如何保證不丟消息