實用docker容器推薦?
推薦MySQLRedisMongoDB等存儲容器,非常方便本地開發和學習。此外,還有一系列類似于nacosgitlabrock
RocketMQ是如何應對每天1500億條的數據處理的?
這個問題太大了。簡單來說,發布者發出消息后,消息數據已經以文件的形式相對有序地存儲在各個服務器中,消費者也相對有序地消費了消息數據。關鍵點是消息的分布式存儲、異步傳輸和內存的零拷貝。
rabbitmq和rocketmq區別?
RabbitMQ基于具有跨語言特性的AMQP協議,支持多種開發語言,用erlang語言編寫,天生具有高并發性。
Rock
JAVA面試如何保證消息不被重復消費?如何保證消息消費的冪等性?
今天,讓我們讓我們看一些方案來確保MQ的冪等性。
01.冪等的概念
我先說說什么是冪等。
當用戶一次或多次請求同一個操作時(多次發送或接收消息),最終結果是一致的,不會因為多次請求而產生副作用;比如同一個訂單付款兩次,客戶最后應該只扣一次。
查詢和刪除:查詢自然是冪等的。在數據不變的前提下,相同查詢條件下一次查詢和多次查詢的結果相同;刪除也是如此。如果同一個條件刪除一次,刪除多次,可能刪除的數據量是不一樣的,但是數據庫里的數據不會因為重復刪除而不一樣。
添加和修改:如果你不t做冪等處理,可能會出現問題;多次添加可能導致多個相同的數據(主鍵是自動生成的);如果只是將部分字段更新為固定值,不會出現冪等問題,但是如果新值需要在舊值上進行處理和計算,比如增加多少,減少多少,那么重復執行后結果就不一樣了。
消息不是等冪的。
1.生產者通常使用超時重傳機制向MQ發送消息,但是如果生產者s消息已經發出,但是由于網絡原因沒有收到確認信息,可能會重新發送,最終導致消息重復發送。
2.消費者消費的過程也差不多。消費者收到來自MQ的消息,但MQ沒有收到確認消息,因此消息可能會重新發送給其他消費者,或者網絡恢復后再次發送給消費者,最終導致重復消費。
03.解決辦法
1.唯一索引
使用唯一索引可以有效防止臟數據的添加:當一個表中存在唯一索引時,并發添加相同數據時會報錯,但這是在單個數據庫、單個表的情況下。只有等待后才有效。如果項目的數據量很大,采用將數據庫分表的策略,那么冪等性的問題就無法再通過數據庫的唯一索引來解決了。
2.全球唯一ID
每封郵件都帶有一個全球唯一的ID。當消費者收到消息時,他在執行之前判斷這個ID是否已經在本地存在。如果不存在,他記錄執行后的ID(存儲在數據庫或Redis中,表示交易已經執行)。如果已經存在,說明該消息已經被消費,不能再次執行。
在許多分布式架構中,全球唯一ID將被用作基本的微服務。當然,這種服務的可靠性極高,或者可以由每個應用程序使用并生成全局唯一的ID算法。然而,總的來說,實現引入全球唯一ID的方案仍然非常麻煩。
3.營業狀況
為了保證消息的冪等性,也可以結合業務流程來考慮。例如,許多業務流程在每一步都是有狀態的。例如,在線購物可能包括:訂單創建、支付和交付,因此保單狀態為"待定付款"付款前,保單狀態可以更改為"等待交付和付款后;然后,如果發起重復扣款,第二次扣款時保單狀態已經改變,扣款失敗。
步驟4:復制表格
如果服務中有一個唯一的標識符,您可以使用一個復制表將這個唯一的表示保存在復制表中。如果重復插入,將被檢查。
例如,在上面的場景中,一個訂單只會支付一次,所以在支付時,將訂單號作為唯一標識符保存在重復表中,以確保支付操作只會發生一次;這種方法也使用唯一ID,但與全局唯一ID不同,這個唯一ID是特定于特定業務的。
我會繼續分享我對Java開發、架構設計、程序員職業發展等方面的看法,希望得到大家的關注。