微服務架構及分佈式事務解決方案

分佈式事務

分佈式事務場景如何設計系統架構及解決數據一致性問題,我的理解最終方案把握如下原則就能夠了,那就是:大事務=小事務(原子事務)+異步(消息通知),解決分佈式事務的最好辦法其實就是不考慮分佈式事務,將一個大的業務進行拆分,整個大的業務流程,轉化成若干個小的業務流程,而後經過設計補償流程從而考慮最終一致性。mysql

什麼是事務

事務(Transaction)及其ACID屬性redis

事務是由一組SQL語句組成的邏輯處理單元,事務具備如下4個屬性,一般簡稱爲事務的ACID屬性:sql

  1. 原子性(Atomicity):事務是一個原子操做單元,其對數據的修改,要麼全都執行,要麼全都不執行。數據庫

  2. 一致性(Consistent):在事務開始和完成時,數據都必須保持一致狀態。這意味着全部相關的數據規則都必須應用於事務的修改,以保持數據的完整性;事務結束時,全部的內部數據結構(如B樹索引或雙向鏈表)也都必須是正確的。微信

  3. 隔離性(Isoation):數據庫系統提供必定的隔離機制,保證事務在不受外部併發操做影響的「獨立」環境執行。這意味着事務處理過程當中的中間狀態對外部是不可見的,反之亦然。網絡

  4. 持久性(Durabe):事務完成以後,它對於數據的修改是永久性的,即便出現系統故障也可以保持。數據結構

典型場景:銀行轉帳業務架構

例如:李雷帳戶中有500塊錢,韓梅梅帳戶有200塊錢,李雷要從本身的帳戶中轉100塊錢給韓梅梅,轉帳(事務)成功執行完成後應該是李雷帳戶減100變爲400,韓梅梅帳戶加100變爲300,不能出現其餘狀況,即在事務開始和結束時數據都必須保持一致狀態(一致性),事務結束時全部的數據及結構都必須是正確的。而且一樣的轉帳操做(同一流水,即一次轉帳操做)不管執行多少次結果都相同(冪等性)。併發

電商場景:流量充值業務異步

再說咱們作的一個項目:中國移動-流量充值能力中心,核心業務流程爲:

  1. 用戶進入流量充值商品購買頁面,選擇流量商品;

  2. 購買流量充值商品,有庫存限制則判斷庫存,生成流量購買訂單;

  3. 選擇對應的支付方式(和包、銀聯、支付寶、微信)進行支付操做;

  4. 支付成功後,近實時流量到帳便可使用流量商品;

此業務流程看似不是很複雜對吧,不涉及到相似電商業務的實物購買,可是我認爲其中的區別並非很大,只是缺乏電商中的物流發貨流程,其餘流程幾乎是同樣的,也有庫存以及優惠折扣等業務存在。

整個系統交互以下圖:


分佈式事務

上述兩個場景的業務需求已經說完了,接着談談分佈式事務,要說分佈式事務那就先聊聊本地事務與分佈式事務:

相同點:首先都是要保證數據正確(即ACID),本地事務與分佈式事務還能夠對應爲: 剛性事務與柔性事務,在我我的理解剛性事務與柔性事務的最大區別就是:一個完整的事務操做是否能夠在 同一物理介質(例如:內存)上同時完成;柔性事務就是一個完整事務須要 跨物理介質或跨物理節點(網絡通信),那麼排它鎖、共享鎖等等就沒有用武之地了(這裏並非指大事務拆小事務【本地事務】後),沒法保證 原子性(Atomicity)完成事務。我的理解分佈式(柔性)事務本質意義上就是-僞事務,柔性事務其實就是根據不一樣的業務場景使用不一樣的方法實現最終一致性,由於能夠根據業務的特性作部分取捨,在業務過程當中能夠容忍必定時間內的數據不一致。

支付寶的柔性事務實現方式有四種分別針對不一樣的業務場景,以下圖:


  1. 兩階段型

  2. 補償型

  3. 異步確保型

  4. 最大努力通知型

流量交易中心的業務場景

經過Dubbo實現了微服務化,大體拆分以下:

  1. 商品服務

  2. 訂單服務

  3. 庫存服務

  4. 支付服務

  5. 直充服務

  6. 消息服務

  7. 等其餘服務

場景一:

庫存數量與訂單數量一致性,採用補償型+最大努力通知型,採用緣由爲不涉及跨機房和長事務(正常狀況下庫存與訂單服務處理很快):

  1. 用戶下單先減庫存,庫存減成功後;

  2. 調用下單服務:

  3. 2-1. 下單成功,兩事務均提交完成;

  4. 2-2. 下單失敗,庫存回滾,兩事務均失敗,此處還有一個保障機制(最大努力通知型),就是若是調用庫存服務異常,肯定庫存回滾失敗了,則放入消息服務(延時消息隊列)分階段定時重試,努力重試保證庫存服務正常後成功回滾。

場景二:

訂單信息、支付信息、充值信息三者之間的一致性,採用異步確保型的緣由是,整個業務鏈路太長且跨不一樣的機房系統,網絡延遲較高,業務方面剛好不須要很是高的實時性,因此採用小事務+異步通知,目前正常狀況下用戶從下單到完成支付到流量到帳平均爲1-5分鐘左右:

  1. 下單成功即訂單服務建立訂單成功併發送支付請求到支付網關係統(訂單狀態-待支付,超過1小時未支付則流轉爲超時未付撤銷,此處用到了RocketMQ的延時消費剛好實現定時器業務場景)。

  2. 返回支付頁面,用戶在支付交易系統完成支付業務流程,支付網關異步通知流量中心,流量中心接收到支付成功狀態後修改訂單狀態-支付成功,並給支付網關返回成功結果(此處併發壓力目前不大,暫時沒有再進行異步解耦)。

  3. 流量中心修改完訂單狀態後,調用消息服務將直充業務放入消息隊列,對直充業務進行解耦(緣由是直充須要調用31省移動CRM系統,此鏈路過長,且部分省CRM系統耗時很是大,每一個省的處理能力不一樣,常常出現20秒以上的超時,所以要考慮部分超時較高的省份拖垮系統,進行業務的削峯填谷);

  4. 3-1. 當直充成功時,修改訂單狀態-已完成;

  5. 3-2. 當直充失敗時(移動特性,例如:直充時正好用戶銷戶或者停機了),修改訂單狀態爲待退款,並調用支付網關係統的退款接口,退款成功後支付網關異步通知流量中心,流量中心修改訂單狀態爲-退款成功;

  6. 3-3. 當直充超時時,調用定時任務服務進行超時重試機制(第一次重試在10分鐘後執行、第二次在30分鐘後、第三次…..),直到最大超時重試次數後還得不到直充結果,訂單狀態會卡在支付成功狀態,依賴T+1對帳稽覈流程保證最終一致性,訂單狀態根據對帳結果流轉爲:已完成或待退款–>退款成功。

場景三:

直充到帳後的消息通知(APP消息推送或短信通知),採用最大努力通知型,這個業務場景比較簡單,在直充成功後,訂單狀態流轉爲已完成,此時經過消息服務進行到帳通知業務的解耦,調用消息服務失敗的狀況下,使用定時任務努力通知。

場景四:

對帳稽覈:

按照支付帳期每日進行T+1對帳,對帳原則:以支付交易記錄爲準,對流量中心訂單記錄+支付網關交易記錄+省CRM充值記錄三方比對,將某些中間狀態的訂單(例如:支付成功、待退款)覈對後將訂單狀態流轉完結(已完成、退款成功)。

結算稽覈:

對帳成功後的數據按期進入結算流程,對支付網關週期內的支付金額與結算數據的金額進行覈對,稽覈成功後進行財務結算流程,將錢結算給省公司,並提供結算明細給省公司,供省公司與直充成本記錄進行復核。

如下是流量中心的部分架構設計,整體原則方向:微服務化

流量中心-架構設計


架構設計思想:在系統初期設計時以及部分硬性環境約束下,咱們根據業務拆分爲多個子系統(微服務):商品服務、訂單服務、庫存服務、支付網關、統一接口平臺、對帳服務、結算服務、網關對接服務等,後續還會增長:帳戶服務、虛擬貨幣服務、卡券服務等等…。按照微服務的核心設計思想,全部服務徹底獨立、隔離,所以全部服務從上至下:請求接入(鏈接管理)、請求處理(計算服務)、數據存儲(存儲服務)進行拆分,接入與計算盡最大可能實現無狀態,數據存儲進行垂直+水平拆分,垂直拆分:商品庫-mysql(讀多寫少,主從架構+讀寫分離)+redis(讀多寫少,集羣方式)、訂單庫-mysql(讀寫均衡,多主多從+水平拆分)、庫存專用庫-redis(分佈式+主備容災)、外部交易系統-支付網關、外部辦理系統-統一接口平臺。

此架構目前已支撐總交易額3.6億,總訂單4680萬,日均交易額500萬,日訂單量50萬,後續業務量持續增長的狀況下按照微服務思想繼續拆分,例如將訂單服務再拆分爲:下單服務、查單服務,直到根據業務需求與系統關係耦合性拆分到最細粒度爲止。

  1. 性能擴展:應用層計算服務(無狀態應用)經過增長服務節點同比提高運算性能,配套質量(性能)監控服務dubbo monitor及整合Netflix的Hystrix熔斷器對業務質量進行管理實現應用層的動態擴縮容。

  2. 容量擴展:數據層存儲服務(有狀態應用)經過對數據水平拆分實現容量的無限擴容,Nosql類方案:Codis中間件;關係型數據庫:Mycat數據庫分庫分表中間件。目前項目中採用twitter的snowflake惟一ID生成器(根據業務場景優化後)本身實現數據的水平拆分和路由規則。

  3. 存儲性能:Nosql:針對讀多寫少場景-使用淘寶的Tedis(多寫隨機讀的特性提升性能),讀寫均衡使用-Codis;Mysql:讀多寫少場景使用一主多從架構(例如商品信息),讀寫均衡場景使用多主多從架構(例如訂單信息)。

總體拆分原則以下圖:

相關文章
相關標籤/搜索