MQ使用心得

首先簡述一下我的業務場景:A系統將需要同步到第三方的報文發送到MQ,同步系統消費MQ做同步;相當於將系統業務與同步獨立拆分;

1.前期調研

技術調研: 技術這塊前期對比了開源的幾種MQ的優缺點,不過公司有自己的MQ平臺,所以就採用的公司的MQ;
業務調研: 雖然只是做同步,爲什麼要用到MQ呢?rest接口它不香嗎?是這樣的,在做同步的時候,需要保證順序,比如說:A報文與B報文之間,必須A報文先同步成功之後,B報文纔可以同步;否則第三方系統那邊會造成數據異常;

2.方案1-基於數據庫

業務系統側,將需要同步的報文都保存到一張表裏面,設置狀態爲未同步;然後同步平臺讀取表中未同步的報文,按報文的創建時間排序後,依次同步;
起初就是這麼設計的,在不斷的去摸索之後,發現有些問題:

1.同步平臺是多節點部署,如何去保證同步表中的一條報文不會被同步多次?

MQ使用心得
這個問題是可以解決的:通過version或者redis分佈式鎖;

2.如何保證報文順序?

假如現在報文爲:
3 {報文}
2 {報文}
1 {報文}
如果server1同步id=3的報文,server2同步id=2的報文;此時,server2先同步成功,server3再同步成功的時候,第三方服務一樣會導致數據錯誤;
MQ使用心得
看似可以解決,但是如果新增一臺server就會相對比較麻煩;

3.方案2-基於MQ

MQ使用心得
MQ是會存在重複消費的行爲,所以需要在消費端做消息的冪等性,如果添加server節點,只需要在hash時,分發到不同的queue就可以;
每個queue代表一種業務類型,每種業務類型之間保證同步順序,如果需要使用全局順序的消息,則需要使用topic來完成;

看似完美的解決方案,其實還有問題:

1.如果消息在消費端處理的過程中,突然停服了,這條消息肯定不會在MQ中丟失,因爲MQ沒有收到成功響應,但是,下次服務啓動時,消費此條消息時,冪等性會將此消息攔截掉,導致消息丟失;

解決思路:保存每條消息到數據庫,並設置狀態爲消費中,當服務啓動時,通過一臺server(爲什麼是一臺,因爲如果是多臺的話,會存在server1檢測到server2在處理正常消費中的消息)來檢查數據表中是否有消費中的記錄,如果有,則先處理消費中的記錄,處理完成後,再開始server1,server2的正常消費;

2.server1消費的比較慢,server1消費v3時,server2消費v6,v2?

MQ使用心得

如果你消費消息之後的邏輯比較簡單,可能會出現上述問題,一樣沒有保證消息的順序性;
出現這種問題可以增加你的queue隊列個數,因爲消費消息時,是通過輪詢的方式來消費不同的queue,queue個數增加了,也提高了每個隊列的循環時間;
當然如果這樣還解決不了,那你可以每臺server對應一個topic來處理;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章