消费消息删除_【进阶之路】可靠消息最终一致性解决方案
導言
大家好,我是南橘,從接觸java到現在也有差不多兩年時間了,兩年時間,從一名連java有幾種數據結構都不懂超級小白,到現在懂了一點點的進階小白,學到了不少的東西。知識越分享越值錢,我這段時間總結(包括從別的大佬那邊學習,引用)了一些平常學習和面試中的重點(自我認為),希望給大家帶來一些幫助
上一章,講了分布式系統中的柔性事務解決方案,并且介紹了一下2PC、3PC、與TCC解決方案。這一次,給大家介紹一種可靠消息最終一致性解決方案,用來實現分布式事務。
- 文章參考石杉的架構筆記
1、可靠消息最終一致性事務
可靠消息最終一致性方案是指當事務發起執行完全本地事務后并發出一條消息,事務參與方(消息消費者)一定能夠接收消息并處理事務成功,此方案強調的是只要消息發給事務參與方最終事務要達到一致。
2、實現可靠消息最終一致性方案
因為RocketMQ支持分布式消息,所以這個方案就用RocketMQ來實現。其實用什么消息中間件都只是業務上的選項,重要的是原理。
應某位同學的要求,我自己畫了一張圖。
- 生產者生產消息
- 消息確認服務器確認消息狀態
- RocketMQ傳遞消息
- 消費者消費消息
流程:
- 1、生產者發送消息給消息確認服務器,消息確認服務器存儲消息,并且把消息狀態改為待確認。
- 2、生產者發送消息后執行本地數據庫,執行成功則確認消息,失敗則刪除消息。
- 3、此時如果是確認消息,那么消息確認服務器就把數據庫里的消息狀態更新為“已發送”,同時將消息發送給MQ。
如果數據庫里更新消息的狀態失敗了,那么就拋異常退出了,就別投遞到MQ。
如果投遞MQ失敗報錯了,那么就要拋異常讓本地數據庫事務回滾。
這倆操作必須得一起成功,或者一起失敗。
- 4、消費者一直等著從MQ消費消息,如果消費到了消息,那么就操作自己本地數據庫
- 5、如果操作成功了,就反過來通知消息確認服務器,說自己處理成功了,然后消息確認服務器就會把消息的狀態設置為“已完成”。
流程是不是很簡單?但是要保證消息的最終一致性和可靠性,還是有不少的工作要做的。
3、如何保證生產者服務對消息的可靠投遞
要保證生產者消息的可靠投遞,生產者需要將消息存入自己的數據庫中,根據據自己的執行結果,調用可靠消息服務的接口。
如果本地數據庫操作執行成功了,那么就找可靠消息服務確認那條消息。如果本地數據庫操作失敗了,那么就找可靠消息服務刪除那條消息。
同時,在消息確認服務器里開發一個后臺定時運行的線程,不停的輪詢檢查各個消息的狀態。
如果上游服務操作完本地數據庫之后,通知可靠消息服務確認消息或者刪除消息的時候,出現了問題。這種情況,消息服務器中的消息一直是“待確認”狀態,就認為這個消息出了點什么問題,可以回調生產者提供的一個接口,確認生產者數據庫操作狀態。
如果上游服務器執行成功了,那么可靠消息服務將消息狀態修改為“已發送”,同時投遞消息到MQ。
如果上游服務執行失敗,那么可靠消息服務將數據庫中的消息刪除即可。
通過這套機制,就可以保證,可靠消息服務一定會嘗試完成消息到MQ的投遞。
4、如何保證消費者服務器對消息的可靠接收
要保消費者消息的可靠接受,也需要在消息確認服務器里開發一個后臺定時運行的線程,通過這個線程,不停的輪詢檢查各個消息的狀態。
如果消息狀態一直是“已發送”的狀態,始終沒有變成“已完成”,那么就說明消費者服務始終沒有處理成功,這個時候消確認服務器就可以再次嘗試重新投遞消息到MQ,讓消費者服務再次處理。
當然,為了保證數據的一致性,不至于出現重復消費的情況,冪等性的實現是必不可少的。
5、保證消息傳遞機制的高可用性
一、RabbitMQ的高可用
我們之前的文章講過,RibbitMQ可以通過搭建集群來實現高可用,但是搭建不同的集群有不同的優劣,這里就不再重復水字數了。
【進階之路】消息隊列——RabbitMQ原理(二)
二、RocketMQ的高可用
RocketMQ是一款出生在高并發分布式時代的消息中間件,所以他本身就是支持高并發和事務的。同時,Name Server無狀態,可線性擴展,天然支持高可用。
- 1、多Master模式
多個Master節點組成的集群,即使有一個節點宕機,對于整個集群來說也沒有什么影響。
缺點:單個Master節點宕機期間, 未被消費的消息在節點恢復之前不可用, 消息的實時性就收到影響。當然,使用同步技術可以讓消息在各個節點之間同步,只是會導致效能和空間利用大幅下降,
- 2、多Master多Slave異步復制模式
在多Master的基礎上, 每個節點都有至少一個的Slave,Master節點可讀可寫,但是Slave節點只讀不寫, 這種情況似于MySQL的主備模式。
優點:單個Master節點宕機期間, Slave節點依舊可以讀取消息。
缺點:異步復制的同步方式有可能導致消息丟失。
- 3、多Master多Slave同步雙寫模式
與多Master多Slave異步復制模式類似, 區別在于Master和Slave之間的數據通過同步的方式傳輸。
優點: 數據與服務都無單點,Master宕機情況下,消息無延遲,服務可用性與數據可用性都非常高。
缺點: 性能比異步復制模式稍低,大約低10%左右,發送單個消息的RT會稍高,目前主宕機后,備機不能自動切換為主機,后續會支持自動切換功能。
三、Kafka 的高可用性
kafka本身是由多個broker組成,每個broker就是一個節點;創建一個topic,這個topic可以劃分為多個partition,每個partition可以存在于不同的broker上,每個partition存放放一部分數據。
所以kafka就是一個分布式消息隊列,一個topic的數據,是分散放在多個機器上的,每個機器就放一部分數據。
(找張圖片來展示一下)
kafka 0.8以后,提供了HA機制,就是replica副本機制。kafka會均勻的將一個partition的所有replica分布在不同的機器上,提高容錯性。若某個broker宕機了,剛好其上有某個partition的leader,那么此時kafka會自動重新選舉出一個新leader,繼續讀寫那個新leader即可。
寫數據的時候:生產者就是leader,將數據落地寫入本地磁盤,接著其他follower主動從leader來拉數據。一旦所有follower同步好數據,會發送ack給leader,leader收到所有follower的ack后,會返回寫成功的消息給生產者。
消費的時候:只會從leader讀,但是只有一個消息已經被所有follower都同步成功返回ack的時候,這個消息才會被讀到,即leader和所有follower上都有了這個消息。
結語
這篇文章基本上就是對于分布式事務的一次總結了。我覺得如果大家想更加深入的了解,可以和我一樣畫畫架構圖,然后嘗試著自己搭建一個簡單的服務。這樣效果真的不錯,雖然在實際工作中大部分公司已經搭建了自己的框架,不過總是要不斷更新的~總有一天我們也會獨當一面不是?
同時需要思維導圖的話,可以聯系我,畢竟知識越分享越香!
總結
以上是生活随笔為你收集整理的消费消息删除_【进阶之路】可靠消息最终一致性解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 批量打印pdf并合并_CAD批量打印攻略
- 下一篇: c语言两个for语句并列执行_C语言两个