寫資料庫同時發mq訊息事務一致性的一種解決方案
一、引子
《事務註解(@Transactional)引起的資料覆蓋故障》一文收到不少反饋。
事務裡不要有rpc,基本原則,sb封裝的太好了,把很多人養傻了,function級別的事務,坑太大。 網友一
這個是mysql資料庫併發更新問題,update未提交,並不能阻塞mq讀取後的select操作。很明顯select會取到未提交的快照,在a事務提交之後b提交覆蓋原值。並且事務中間是絕對不應該有外部呼叫的 網友二
去哪qmq的玩法是利用資料庫的事務 所有庫上加一個mq的邏輯庫 mq實際先提交一條資料到mq庫 再用統一的消費者消費mq庫 實現訊息的隔離和最終一致 網友三
隨著公司業務的增長,單體應用架構很難滿足業務快速迭代以及效能方面的需求,都會進行服務化改造,按照業務等要素將原來龐大的單體應用拆分成不同的服務。那麼在進行服務化改造之前首先就是面臨是服務化基礎設施的技術選型,其中最重要的就是服務之間的通訊中介軟體。服務之間的通訊可以分為同步方式和非同步方式。同步的方式的代表就是 RPC,非同步方式一般會選用mq。
二、問題的現實意義
如果我們要在服務化拆分中使用訊息佇列,那麼我們需要解決哪些問題呢?首先去哪兒網提供了旅遊產品線上預訂服務,那麼就涉及電商交易,在電商交易中我們認為資料的一致性是非常關鍵的要素。那麼我們的 MQ 必須提供一致性保證。
MQ 提供一致性保證又分為兩個方面。發訊息時我們如何確保業務操作和發訊息是一致的,也就是不能出現業務操作成功訊息未發出或者訊息發出了但是業務並沒有成功的情況。舉例來說,支付服務使用訊息通知出票服務,那麼不能出現支付成功,但是訊息沒有發出,這會引起使用者投訴;但是也不能出現支付未成功,但是訊息發出最後出票了,這會導致公司損失。總結一下就是發訊息和業務需要有事務保證。一致性的另一端是消費者,比如消費者臨時出錯或網路故障,我們如何確保訊息最終被處理了。那麼我們透過消費 ACK 和重試來達到最終一致性。
三、利用資料庫事務解決一致性問題
提到一致性,大家肯定就想到事務,而一提到事務,肯定就想到關係型資料庫,那麼我們是不是可以藉助關係型 DB 裡久經考驗的事務來實現這個一致性呢。我們以 MySQL 為例,對於 MySQL 中同一個例項裡面的 db,如果共享相同的 Connection 的話是可以在同一個事務裡的。以下圖為例,我們有一個 MySQL 例項監聽在 3306 埠上,然後該例項上有 A,B 兩個 DB,那麼下面的虛擬碼是可以跑在同一個事務裡的
有了這層保證,我們就可以透明的實現業務操作和訊息傳送在同一個事務裡了,首先我們在公司所有 MySQL 例項裡初始化出一個 message db,這個可以放到自動化流程中(據說在去哪兒由運維團隊完成),對應用透明。然後我們只要將發訊息與業務操作放到同一個 DB 事務裡即可。
我們來看一個實際的場景,在支付場景中,支付成功後我們需要插入一條支付流水,並且傳送一條支付完成的訊息通知其他系統。那麼這裡插入支付流水和傳送訊息就需要是一致的,任何一步沒有成功最後都會導致問題。那麼就有下面的程式碼
上面的程式碼可以用下面的虛擬碼解釋
實際上在 producer.sendMessage 執行的時候,訊息並沒有透過網路傳送出去,而僅僅是往業務 DB 同一個例項上的訊息庫插入一條記錄,然後註冊事務的回撥,在這個事務真正提交後訊息才從網路傳送出去,這個時候如果傳送到 server 成功的話訊息會被立即刪除掉。而如果訊息傳送失敗則訊息就留在訊息庫裡,這個時候我們會有一個補償任務會將這些訊息從訊息庫裡撈出然後重新傳送,直到傳送成功。整個流程就如下圖所示
1、begin tx 開啟本地事務
2、do work 執行業務操作
3、insert message 向同例項訊息庫插入訊息
4、end tx 事務提交
5、send message 網路向 server 傳送訊息
6、reponse server 回應訊息
7、delete message 如果 server 回覆成功則刪除訊息
8、scan messages 補償任務掃描未傳送訊息
9、send message 補償任務補償訊息
10、delete messages 補償任務刪除補償成功的訊息
四、更多的東西
去哪兒完整的方案,還包括了訊息的儲存模型以及延遲佇列的儲存模型,分別解決效能及業務問題。
當然訊息儲存模型這部分,本公眾號之前關於IM的文章的做法也值得參考。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31556438/viewspace-2668318/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 資料庫與快取資料一致性解決方案資料庫快取
- 視角 | 微服務的資料一致性解決方案微服務
- 聊聊Zookeeper的資料一致性解決方案
- 資料庫行業解決方案都寫了啥資料庫行業
- 微服務資訊同步方案(資料依賴一致性問題)微服務
- 資料庫和快取雙寫一致性方案總結分析資料庫快取
- windows平臺的分散式微服務解決方案(4)--資料庫的讀寫分離Windows分散式微服務資料庫
- 快取與資料庫雙寫一致性幾種策略分析快取資料庫
- 分散式之資料庫和快取雙寫一致性方案解析分散式資料庫快取
- 分散式之資料庫和快取雙寫一致性方案(二)分散式資料庫快取
- 一次資料庫匯入解決方案資料庫
- 快取與資料庫的雙寫一致性快取資料庫
- MySQL資料庫資料一致性比對的方案的探討MySql資料庫
- 【物聯網】一種新的工業資料通訊解決方案OPC UA TSN
- 雲資料庫安全解決方案資料庫
- 資料庫回檔解決方案資料庫
- [譯]2018 年度最佳資料庫即服務解決方案資料庫
- 分散式事務解決方案(二)【基於可靠訊息的最終一致性】分散式
- 分散式事務瞭解嗎?你們的多個服務間資料一致性解決方案是什麼?分散式
- 一種方便的跨域開發解決方案跨域
- 資料庫與快取雙寫一致性資料庫快取
- RocketMQ系列(七)事務訊息(資料庫|最終一致性)MQ資料庫
- 分散式事務解決方案-RocketMQ實現可靠訊息最終一致性分散式MQ
- 深入剖析資料庫核心之事務的本質 | 附下一代分散式資料庫 OceanBase 解決方案資料庫分散式
- 快取與資料庫雙寫,不一致問題及解決方案快取資料庫
- 如何保證mongodb和資料庫雙寫資料一致性?MongoDB資料庫
- Java多執行緒:資料一致性問題及解決方案Java執行緒
- 高併發下資料冪等問題的9種解決方案
- 分散式事務(2)---強一致性分散式事務解決方案分散式
- 同時訪問內外網解決方案
- 基於Spring的Web專案執行時切換資料來源的一種解決方案SpringWeb
- JPA使用pg資料庫時,bool欄位不能跨庫遷移的解決方案資料庫
- 微服務架構下,解決資料一致性問題的實踐微服務架構
- Laravel資料庫測試的另一種方案-SQLiteLaravel資料庫SQLite
- 分散式事務解決方案(三)【基於可靠訊息的最終一致性(獨立訊息服務實現)】分散式
- 一個簡化、落地的實時資料倉儲解決方案
- 深入理解分散式之資料庫和快取雙寫一致性方案解析分散式資料庫快取
- django REST fromework 序列化時多次查詢資料庫的解決方案DjangoREST資料庫