您好,登錄后才能下訂單哦!
[TOC]
在電商領(lǐng)域等互聯(lián)網(wǎng)場景下,傳統(tǒng)的事務(wù)在數(shù)據(jù)庫性能和處理能力上都暴露出了瓶頸。柔性事務(wù)有兩個(gè)特性:基本可用和柔性狀態(tài)。所謂基本可用是指分布式系統(tǒng)出現(xiàn)故障的時(shí)候允許損失一部分的可用性。柔性狀態(tài)是指允許系統(tǒng)存在中間狀態(tài),這個(gè)中間狀態(tài)不會影響系統(tǒng)整體的可用性,比如數(shù)據(jù)庫讀寫分離的主從同步延遲等。柔性事務(wù)的一致性指的是最終一致性。
消息中間件在分布式系統(tǒng)中的核心作用就是異步通訊、應(yīng)用解耦和并發(fā)緩沖(也叫作流量削峰)。在分布式環(huán)境下,需要通過網(wǎng)絡(luò)進(jìn)行通訊,就引入了數(shù)據(jù)傳輸?shù)牟淮_定性,也就是CAP理論中的分區(qū)容錯(cuò)性。
消息發(fā)送一致性是指產(chǎn)生消息的業(yè)務(wù)動作與消息發(fā)送一致,也就是說如果業(yè)務(wù)操作成功,那么由這個(gè)業(yè)務(wù)操作所產(chǎn)生的消息一定要發(fā)送出去,否則就丟失。
處理方式一
public void completeOrderService() {
// 處理訂單
order.process();
// 發(fā)送會計(jì)原始憑證消息
pipe.sendAccountingVouchetMessage();
}
在上面的情況中,如果業(yè)務(wù)操作成功,執(zhí)行的消息發(fā)送之前應(yīng)用發(fā)生故障,消息發(fā)送不出去,導(dǎo)致消息丟失,將會產(chǎn)生訂單系統(tǒng)與會計(jì)系統(tǒng)的數(shù)據(jù)不一致。如果消息系統(tǒng)或者網(wǎng)絡(luò)異常,也會導(dǎo)致消息發(fā)送不出去,也會造成數(shù)據(jù)不一致。
處理方式二
public void completeOrderService() {
// 發(fā)送會計(jì)原始憑證消息
pipe.sendAccountingVouchetMessage();
// 處理訂單
order.process();
}
如果將上面的兩個(gè)操作調(diào)換一下順序,這種情況就會更加不可控了,消息發(fā)出去了業(yè)務(wù)訂單可能會失敗,會造成訂單系統(tǒng)與業(yè)務(wù)系統(tǒng)的數(shù)據(jù)不一致。那么JMS標(biāo)準(zhǔn)中的XA協(xié)議是否可以保障發(fā)送的一致性?
JMS協(xié)議標(biāo)準(zhǔn)的API中,有很多以XA開頭的接口,其實(shí)就是前面講到的支持XA協(xié)議(基于兩階段提交協(xié)議)的全局事務(wù)型接口。
XAConnection.class
XAConnectionFactory.class
XAQueueConnection.class
XAQueueConnectionFactory.class
XASession.class
XATopicConnection.class
XATopicConnectionFactory.class
XATopicSession.class
但是在上面的處理流程中,任何一個(gè)環(huán)節(jié)都有可能出現(xiàn)問題。
對于未確認(rèn)的消息,采用按規(guī)則重新投遞的方式進(jìn)行處理。對于以上流程,消息重復(fù)發(fā)送會導(dǎo)致業(yè)務(wù)處理接口出現(xiàn)重復(fù)調(diào)用的問題。消息消費(fèi)過程中消息重復(fù)發(fā)送的主要原因就是消費(fèi)者成功接收處理完消息后,消息中間件沒有及時(shí)更新投遞狀態(tài)導(dǎo)致的。如果允許消息重復(fù)發(fā)送,那么消費(fèi)方應(yīng)該實(shí)現(xiàn)業(yè)務(wù)接口的冪等性設(shè)計(jì)。
示例消息數(shù)據(jù)表:
名稱 | 數(shù)據(jù)類型 | 允許空 | 默認(rèn)值 | 屬性 | 釋義 |
---|---|---|---|---|---|
uuid | varchar(50) | No | — | unique | UUID |
version | int(11) | No | 0 | — | 版本號 |
editer | varchar(100) | Yes | NULL | — | 修改者 |
creater | varchar(100) | Yes | NULL | — | 創(chuàng)建者 |
edit_time | datetime | Yes | 0000-00-00 00:00:00 | — | 最后修改時(shí)間 |
create_time | datetime | No | 0000-00-00 00:00:00 | — | 創(chuàng)建時(shí)間 |
msg_id | varchar(50) | No | — | — | 消息ID |
msg_body | longtext | No | — | — | 消息內(nèi)容 |
msg_date_type | varchar(50) | Yes | — | — | 消息數(shù)據(jù)類型 |
consumer_queue | varchar(100) | No | — | — | 消費(fèi)隊(duì)列 |
send_times | int(6) | No | 0 | — | 消息重發(fā)次數(shù) |
is_dead | varchar(20) | No | — | — | 是否死亡 |
status | varchar(20) | No | — | — | 狀態(tài) |
remark | varchar(200) | Yes | — | — | 備注 |
field0 | varchar(200) | Yes | — | — | 擴(kuò)展字段0 |
field1 | varchar(200) | Yes | — | — | 擴(kuò)展字段1 |
field2 | varchar(200) | Yes | — | — | 擴(kuò)展字段2 |
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。