日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java消息队列mq_我爱java系列---【消息队列(rabbitmq)】

發(fā)布時(shí)間:2023/12/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java消息队列mq_我爱java系列---【消息队列(rabbitmq)】 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用消息隊(duì)列來避免分布式事務(wù)

如果仔細(xì)觀察生活的話,生活的很多場(chǎng)景已經(jīng)給了我們提示。

比如在北京很有名的姚記炒肝點(diǎn)了炒肝并付了錢后,他們并不會(huì)直接把你點(diǎn)的炒肝給你,往往是給你一張小票,然后讓你拿著小票到出貨區(qū)排隊(duì)去取。

為什么他們要將付錢和取貨兩個(gè)動(dòng)作分開呢?原因很多,其中一個(gè)很重要的原因是為了使他們接待能力增強(qiáng)(并發(fā)量更高)。

還是回到我們的問題,只要這張小票在,你最終是能拿到炒肝的。同理轉(zhuǎn)賬服務(wù)也是如此,當(dāng)用戶A賬戶扣除1萬后,

我們只要生成一個(gè)憑證(消息)即可,這個(gè)憑證(消息)上寫著“讓用戶B賬戶增加 1萬”,只要這個(gè)憑證(消息)能可靠保存,

我們最終是可以拿著這個(gè)憑證(消息)讓用戶B賬戶增加1萬的,即我們能依靠這個(gè)憑證(消息)完成最終一致性。

1 如何可靠保存憑證(消息)

有兩種方法:

1.1 業(yè)務(wù)與消息耦合的方式

用戶A在完成扣款的同時(shí),同時(shí)記錄消息數(shù)據(jù),這個(gè)消息數(shù)據(jù)與業(yè)務(wù)數(shù)據(jù)保存在同一數(shù)據(jù)庫實(shí)例里(消息記錄表表名為message);

上述事務(wù)能保證只要用戶A賬戶里被扣了錢,消息一定能保存下來。

當(dāng)上述事務(wù)提交成功后,我們通過實(shí)時(shí)消息服務(wù)將此消息通知用戶B,用戶B處理成功后發(fā)送回復(fù)成功消息,用戶A收到回復(fù)后刪除該條消息數(shù)據(jù)。

1.2 業(yè)務(wù)與消息解耦方式

上述保存消息的方式使得消息數(shù)據(jù)和業(yè)務(wù)數(shù)據(jù)緊耦合在一起,從架構(gòu)上看不夠優(yōu)雅,而且容易誘發(fā)其他問題。為了解耦,可以采用以下方式。

1)用戶A在扣款事務(wù)提交之前,向?qū)崟r(shí)消息服務(wù)請(qǐng)求發(fā)送消息,實(shí)時(shí)消息服務(wù)只記錄消息數(shù)據(jù),而不真正發(fā)送,只有消息發(fā)送成功后才會(huì)提交事務(wù);

2)當(dāng)用戶A扣款事務(wù)被提交成功后,向?qū)崟r(shí)消息服務(wù)確認(rèn)發(fā)送。只有在得到確認(rèn)發(fā)送指令后,實(shí)時(shí)消息服務(wù)才真正發(fā)送該消息;

3)當(dāng)用戶A扣款事務(wù)提交失敗回滾后,向?qū)崟r(shí)消息服務(wù)取消發(fā)送。在得到取消發(fā)送指令后,該消息將不會(huì)被發(fā)送;

4)對(duì)于那些未確認(rèn)的消息或者取消的消息,需要有一個(gè)消息狀態(tài)確認(rèn)系統(tǒng)定時(shí)去用戶A系統(tǒng)查詢這個(gè)消息的狀態(tài)并進(jìn)行更新。為什么需要這一步驟,

舉個(gè)例子:假設(shè)在第2步用戶A扣款事務(wù)被成功提交后,系統(tǒng)掛了,此時(shí)消息狀態(tài)并未被更新為“確認(rèn)發(fā)送”,從而導(dǎo)致消息不能被發(fā)送。

優(yōu)點(diǎn):消息數(shù)據(jù)獨(dú)立存儲(chǔ),降低業(yè)務(wù)系統(tǒng)與消息系統(tǒng)間的耦合;

缺點(diǎn):一次消息發(fā)送需要兩次請(qǐng)求;業(yè)務(wù)處理服務(wù)需要實(shí)現(xiàn)消息狀態(tài)回查接口。

2 如何解決消息重復(fù)投遞的問題

還有一個(gè)很嚴(yán)重的問題就是消息重復(fù)投遞,以我們用戶A轉(zhuǎn)賬到用戶B為例,如果相同的消息被重復(fù)投遞兩次,那么我們用戶B賬戶將會(huì)增加2萬而不是1萬了。

為什么相同的消息會(huì)被重復(fù)投遞?比如用戶B處理完消息msg后,發(fā)送了處理成功的消息給用戶A,正常情況下用戶A應(yīng)該要?jiǎng)h除消息msg,但如果用戶A這時(shí)候悲劇的掛了,

重啟后一看消息msg還在,就會(huì)繼續(xù)發(fā)送消息msg。

解決方法很簡單,在用戶B這邊增加消息應(yīng)用狀態(tài)表(message_apply),通俗來說就是個(gè)賬本,用于記錄消息的消費(fèi)情況,每次來一個(gè)消息,

在真正執(zhí)行之前,先去消息應(yīng)用狀態(tài)表中查詢一遍,如果找到說明是重復(fù)消息,丟棄即可,如果沒找到才執(zhí)行,同時(shí)插入到消息應(yīng)用狀態(tài)表(同一事務(wù))

總結(jié)

以上是生活随笔為你收集整理的java消息队列mq_我爱java系列---【消息队列(rabbitmq)】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。