一行代碼,保障分佈式事務一致性—GTS:微服務架構下分佈式事務解決方案

摘要: 雖然微服務如今如火如荼,但對其實踐其實仍處於初級階段。即便互聯網巨頭的實踐也大可能是試驗層面,鮮有核心業務系統微服務化的案例。GTS是目前業界第一款,也是惟一的一款通用的解決微服務分佈式事務問題的中間件,並且能夠保證數據的強一致性。本文將對GTS作出深刻解讀。web

微服務倡導將複雜的單體應用拆分爲若干個功能簡單的、鬆耦合的服務,這樣能夠下降開發難度、加強擴展性、便於敏捷開發。概念2012年提出迅速火遍全球,被愈來愈多的開發者推崇,不少互聯網行業巨頭、開源社區等都開始了微服務的討論和實踐。根據Netflix雲架構總監Adrian Cockcrof,Hailo有160個不一樣服務構成,NetFlix有大約600個服務。國內方面,阿里巴巴、騰訊、360、京東、58等不少互聯網公司都進行了微服務化改造。當前微服務的開發框架也有幾十種之多,比較著名的有Dubbo、SpringCloud、thrift 、grpc等。redis

1 分佈式事務解決方案及其弊端
雖然微服務如今如火如荼,但對其實踐其實仍處於初級階段。即便互聯網巨頭的實踐也大可能是試驗層面,鮮有核心業務系統微服務化的案例。而對於不少中小型互聯網公司,鑑於經驗、技術實力等問題,微服務落地更加困難。世界著名的軟件架構大師Chris Richardson在《Introduction to Microservices》一文中也直接了當的指出了微服務當前存在的問題:spring

從單體應用拆分爲分佈式系統帶來的複雜性。開發者須要選擇或實現基於消息或者RPC模式的進程間通信機制,另外開發者也要寫額外的代碼去處理對於目的服務請求可能存在的請求緩慢或者請求不可用致使的局部故障問題。
單體應用拆分所致使的數據庫架構的拆分。應用更新多個業務記錄很是常見,單體應用實現也比較簡單。然而在微服務架構下,應用不得不調用多個微服務去更新多個數據庫。通常很難使用分佈式事務解決,不只僅是由於CAP理論,還由於一些流行的NoSQL數據庫和Message Queue系統壓根也不支持(攤手)。最後還得繞回最終一致性方案,這個方案對開發者來說也是很是有挑戰性。
測試微服務架構的應用也是更加複雜的。由於服務之間可能有諸多調用,測試一個服務將不得不啓動其餘服務。
部署、運維一個微服務架構的應用變的更加困難。微服務通常由大量的服務組成,每一個服務還有多個運行實例!將會有更多變化的部分須要去配置、部署、擴展、監控。此外還須要實現一個服務發現機制讓其餘服務找到它須要通訊的服務的地址。
對於第一和第三個問題,筆者認爲隨着RPC框架的成熟,已經逐漸獲得解決。例如dubbo能夠支持rmi、hessian、http、webservice、thrift、redis等多種通信協議,springcloud能夠很是好的支持restful調用。spring體系下應用的測試也變的愈來愈簡單。對於第四個問題,隨着docker、devops技術的發展以及各公有云paas平臺自動化運維工具的推出,微服務的部署與運維會變得愈來愈容易。sql

而對於Chris Richardson提到的第二個問題,如今尚未通用方案很好的解決微服務產生的事務問題。分佈式事務已經成爲微服務落地最大的阻礙,也是最具挑戰性的一個技術難題。 爲此,本文將深刻和你們探討微服務架構下,分佈式事務的各類解決方案,並重點爲你們解讀阿里巴巴提出的分佈式事務解決方案----GTS。該方案中提到的GTS是目前業界第一款,也是惟一的一款通用的解決微服務分佈式事務問題的中間件,並且能夠保證數據的強一致性。docker

2 SOA分佈式事務解決方案
在微服務以前,信息系統中的服務大多基於SOA的理念設計(SOA與微服務的區別),服務相對比較重。對於服務調用產生的分佈式事務問題,在SOA時代,就有一些解決方案。比較著名的有基於XA協議的方案、TCC方案、消息最終一致性方案。數據庫

2.1基於XA協議的方案
該方案最先由oracle提出用於解決跨數據訪問的事務問題,是一種強一致性的解決方案,由事務協調器和本地資源管理器共同完成。事務協調器和資源管理器間經過XA協議進行通訊。XA協議實現的原理入下圖所示,共分爲兩個階段,也就是咱們常說的兩階段協議。
圖片描述服務器

兩階段方案在解決數據庫分佈式事務問題方面應用很是普遍,oracle、Mysql等主流關係數據庫均支持XA協議,並且ocenbase、DCDB等著名的分佈式數據庫也都基於兩階段協議。在解決服務事務問題上,其實 XA協議不是隻能做用於單個服務內部的多資源場景,跨服務的多資源場景也是能夠的,只不過須要額外的事務傳遞機制。但其都有致命的缺點,性能不理想。因爲須要等到各分支事務都就緒後全局事務纔開始提交,因此每一個事務鎖定數據的時間較長,XA方案所以很難知足高併發場景。並且在解決微服務問題時XA方案的性能問題將會被放大。由於應用在訪問服務的調用方式、網絡環境等要比訪問數據庫複雜的多。例如,應用和其訪問的數據庫一般在一個局域網中,而其經過rpc調用的服務則可能屬於另外一個網絡或者在公網上,其時延更長、出故障的機率更高。這將致使數據鎖定時間和系統併發度進一步下降。因此XA方案基本不適合解決微服務的事務問題。restful

2.2TCC方案
TCC方案應用是目前呼聲最高,也是落地最多的一個方案。當前也有一些開源的TCC框架實現,如TCC-Transaction、ByteTCC。TCC方案實際上是兩階段方案的一種改進,其將本地資源管理器的功能融入到了業務實現中。其將整個業務邏輯顯示的分紅了Try、Confirm、Cancel三部分。try部分完成業務的準備工做,confirm部分完成業務的提交,cancel部分完成事務的回滾。基本原理以下圖所示。網絡

圖片描述
事務開始時,業務應用會向事務協調器註冊啓動事務。以後業務應用會調用全部服務的try接口,至關於XA的第一階段。若是有任何一個服務的try接口調用失敗會向事務協調器發送事務回滾請求,不然發送事務提交請求。事務協調器收到事務回滾請求後會依次調用事務的confirm接口,不然調用cancel接口回滾,這至關於XA的第二階段。若是第二階段接口調用失敗,會進行重試。架構

TCC方案經過經過三個接口很好的規避了長時間數據加鎖的問題,業務表在每一個接口調用完畢便可釋放,這很大程度上提升了業務的併發度,這也是TCC方案最大的優點。因此在SOA時期,TCC方案被不少金融、電商的業務系統大量使用。
固然TCC方案也有不足之處,集中表如今如下兩個方面:

開發工做量大。它將部分資源管理器的功能融入到每一個服務的開發中,致使服務的每一個接口都須要實現try、confirm、cancle,還須要實現事務協調器,開發量不僅翻了一倍。
實現難度大。系統須要記錄每一個應用的服務調用鏈路。我前面講過rpc調用狀況比較複雜,因爲網絡情況、系統故障等調用失敗被視爲常態,必須按照不一樣的失敗緣由實現不一樣策略的回滾。爲了知足一致性的要求,二階段無論調用confirm仍是cancle都必須調用成功,若是一次調用不成功,事務協調器必須嘗試重試。這就要求confirm和cancle接口必須實現冪等。
上述緣由致使TCC方案大可能是被研發實力較強、有迫切需求的大公司所採用。其將分佈式事務變成一種所謂的「貴族技術」,中小型企業因爲人員有限、技術實力薄弱,很難落地。並且筆者認爲微服務倡導的是服務的輕量化、易部署,而TCC方案將不少事務的處理功能融入到業務中,對業務侵入性過高,致使服務邏輯複雜,比較適合比較重的服務。

2.3 消息事務一致性方案
消息一致性方案是經過消息中間件保證上、下游應用數據操做的一致性。基本思路是將本地操做和發送消息放在一個事務中,保證本地操做和消息發送要麼二者都成功或者都失敗。下游應用向消息系統訂閱該消息,收到消息後執行相應操做。
如下單業務爲例進行說明,下單基本流程是先存儲訂單信息,而後扣相應商品的庫存,兩個操做必須在一個事務中。以下圖,業務應用首先調用訂單服務,訂單存儲成功後,訂單服務會經過消息處理服務投遞訂單消息到MQ。庫存服務從MQ收到消息後進行扣庫存操做,若是執行成功會向消息處理服務發送通知。消息處理服務會實時監測訂單消息是否超時,若是超時會從新投遞到MQ中,以驅動庫存服務進行扣庫存操做。若是扣庫存操做執行失敗後,庫存服務後續還會從MQ接收到相同的訂單消息,須要屢次重複執行,直到成功或者進行人工干預。庫存服務須要實現冪等。

圖片描述
消息方案從本質上講是將分佈式事務轉換爲兩個本地事務,而後依靠下游業務的重試機制達到最終一致性。相對TCC方案來說,消息方案技術難度相對低,落地較容易,若是對一致性不敏感的應用也是一個不錯的選擇。美國著名電商e-bay以及國內的蘑菇街都作過嘗試。消息一致性方案的不足之處是其對應用侵入性較高,應用須要基於消息接口進行改造,並且須要建設專門的消息系統,成本較高。

3 GTS--微服務分佈式事務解決方案
GTS是一款分佈式事務中間件,由阿里巴巴中間件部門研發,能夠爲微服務架構中的分佈式事務提供一站式解決方案。GTS方案的基本思路是:將分佈式事務與具體業務分離,在平臺層面開發通用的事務中間件GTS,由事務中間件協調各服務的調用一致性,負責分佈式事務的生命週期管理、服務調用失敗的自動回滾。

GTS方案有三方面的優點,首先它將微服務從分佈式事務中解放出來,微服務的實現不須要再考慮反向接口、冪等、回滾策略等複雜問題,只須要業務本身的接口便可,大大下降了微服務開發的難度與工做量。將分佈式事務從所謂的「貴族技術」變爲你們都能使用的「平民技術 」,有利於微服務的落地與推廣。 其次,GTS對業務代碼幾乎沒有侵入,只須要經過註解@TxcTransaction界定事務邊界便可,微服務接入GTS的成本很是低。第三,性能方面GTS也很是優秀,是傳統XA方案的8~10倍。

3.1 基本原理
GTS中間件主要包括客戶端(GTS Client)、資源管理器(GTS RM)和事務協調器(GTS Server)三部分。GTS Client主要完成事務的發起與結束。GTS RM完成分支事務的開啓、提交、回滾等操做。GTS Server主要負責分佈式事務的總體推動,事務生命週期的管理。
圖片描述

GTS和微服務集成後的結構圖如上圖所示。GTS Client須要和業務應用集成部署,RM與微服務集成部署。當業務應用發起服務調用時,首先會經過GTS Client向TC註冊新的全局事務。以後GTS Server會給業務應用返回全局惟一的事務編號xid。業務應用調用服務時會將xid傳播到服務端。微服務在執行數據庫操做時會經過GTS RM向GTS Server註冊分支事務,並完成分支事務的提交。若是A、B、C三個服務均調用成功,GTS Client會通知GTS Server結束事務。假設C調用失敗,GTS Client會要求GTS Server發起全局回滾。而後由各自的RM完成回滾工做。

3.2 GTS的關鍵機制
可用性
GTS服務也是由多個節點構成的高可用集羣,能夠彈性擴張,能夠接收高併發的客戶端請求。能夠支持跨機房部署,支持同城容災和兩地三中心容災。任何異常狀況下的保證高可用。
自動回滾策略
當有微服務調用失敗時,GTS服務能夠驅動各微服務的RM替微服務完成調用的回滾工做。舉個轉帳的例子,轉帳應用一般調用存款服務和扣款服務完成轉帳功能。先調用扣款服務從A帳戶扣掉100元,而後調用存款服務向B帳戶中存款100元。若是轉帳應用在調用存款服務失敗時,GTS Client會要求GTS Server發起回滾,而後通知扣款服務對應的RM,RM會直接在A帳戶增長100元。而後GTS Server通知轉帳應用回滾成功。從這個過程能夠看到,在調用服務失敗後,其實微服務不用作任何工做,而是由RM替微服務執行反向操做,也很天然的避免了冪等操做。TCC方案中,事務協調器須要顯示調用微服務的反向向接口,若是反向接口調用失敗還須要不斷重試。
可擴展性
有些狀況下,應用須要調用第三方系統的接口或者不是基於GTS開發的微服,GTS沒法接入到這些服務的實現中。此時須要用到GTS的MT模式。GTS的MT模式能夠等價於TCC模式。
MT模式預留了一階段和二階段的提交接口,容許應用介入GTS的兩階段提交。應用將提交及回滾接口註冊後,GTS會自動完成調用。

隔離級別
GTS目前支持讀未提交和讀已提交兩種隔離級別。
3.3 GTS與其餘方案的對比

  1. 和XA方案對比

相比XA方案,GTS更加通用,能夠對上層業務屏蔽底層實現細節,對業務幾乎沒有侵入。這一點在微服務時代特別有用,微服務面對的是大量的中小企業,甚至是我的開發者,業務訴求不盡相同,普適、標準的分佈式事務產品是很是有必要的,可讓開發者從底層技術細節中脫離出來,更專一於業務邏輯的實現,從而得到更高效、快速的業務發展。兩個方案均可以遵循ACID特性,均可以實現事務的強一致性。GTS性能要比XA方案高。

  1. 和TCC方案對比

GTS方案和TCC方案最大的區別是實現分佈式事務實現的層面不一樣。TCC方案選擇從業務層面實現分佈式事務功能,將事務的回滾、重試等功能在微服務中實現。而GTS選擇從中間件層面解決分佈式事務問題,對微服務幾乎無侵入。兩個方案均可以得到比較好的性能,均可以保證調用的一致性。TCC方案實現難度比較大,適合技術實力較強的團隊。GTS方案能夠實現事務的強一致性,另外採用GTS方案後微服務會更簡單,耦合性也很是低。TCC主要提供開發框架,實現須要依賴業務方,而GTS是完整的分佈式事務解決方案,全部分佈式事務問題不須要業務方介入。

  1. 和消息最終一致性對比

相比消息方案,GTS方案侵入性很是低,能夠實現數據的強一致性。採用消息方案,上下游服務之間有很強的耦合性,測試、部署都不是很方便,須要單獨建設消息系統。不過消息方案實現相對簡單,若是對一致性要求不高,也是一個選擇。

3.4 GTS的應用場景
GTS可應用在涉及服務調用的多個領域,包括但不限於金融支付、電信、電子商務、快遞物流、廣告營銷、社交、即時通訊、手遊、視頻、物聯網、車聯網等,詳細介紹能夠閱讀 《GTS--阿里巴巴分佈式事務全新解決方案》一文。

3.5 GTS的輸出形式
GTS目前有三種輸出形式:經過公有云平臺輸出、經過公網雲服務輸出、經過專有云平臺輸出。

1 經過公有云平臺輸出
這種輸出形式主要面向阿里雲用戶。若是用戶的業務系統已經部署到阿里雲上,能夠直接申請開通公有云GTS。開通後業務應用便可經過GTS保證服務調用的一致行。這種使用場景下,業務系統和GTS間的網絡環境比較理想,GTS能提供更低的響應時間。
圖片描述

公有云提供了比較豐富的與dubbo、SpringCloud等集成的樣例,能夠點擊查看。

2 經過公網雲服務輸出
這種輸出形式主要面向於非阿里雲的用戶,使用更加方便、靈活,業務系統只要能鏈接互聯網便可享受GTS提供的雲服務。在網絡抖動和閃斷的狀況下,GTS仍能保證服務調用的一致性。在正常網絡環境下,以包含兩個本地事務的全局事務爲例,事務完成時間在20ms左右,業務能夠輕鬆實現1000TPS以上分佈式事務,能夠知足絕大多數業務系統的須要。也能夠用於本地的開發和測試 。
圖片描述
如今提供了sample-txc-simple和sample-txc-sample兩個樣例,sample-txc-simple是GTS的入門的基礎樣例,點擊下載後,搭建好本地的數據庫環境就能夠直接運行樣例。sample-txc-dubbo是GTS和dubbo框架集成的樣例,也能夠直接在本地機器運行。

3 經過專有云平臺輸出
這種形式主要面向於已建設了本身專有云平臺的大用戶,GTS能夠直接部署到用戶的專有云平臺上,爲專有云提供分佈式事務服務。目前國家電網公司、中國郵政、浙江菸草等特大型企業的專有云都使用GTS,保證數據一致性。

3.6 GTS的使用方式
GTS對應用的侵入性很是低,使用也很是簡單。下面以訂單存儲應用爲例說明。訂單業務應用經過調用訂單服務和庫存服務完成訂單業務,服務開發框架爲dubbo。

1 訂單業務應用
在業務函數外圍使用@TxcTransaction註解便可開啓分佈式事務。dubbo應用經過隱藏參數將GTS的事務xid傳播到服務端。

@TxcTransaction(timeout = 1000 * 10)
public void Bussiness(OrderServiceInterface os,StockServiceInterface ss)
{
//獲取xid
String xid = TxcContext.getCurrentXid();
//1:調用訂單服務,建立訂單
//經過dubbo的隱形參數將txcid傳到服務端
RpcContext.getContext().setAttachment("xid",xid);
int ret = os.setOrder(new Order(pid,num,new Date()));//調用訂單服務
//2:調用庫存服務,扣庫存
RpcContext.getContext().setAttachment("xid",xid);
}

2 服務端使用方式
庫存服務

public int setStock(Stock sk) {
//經過dubbo上下文獲取xid
String xid = RpcContext.getContext().getAttachment("xid");
//將事務id綁定到服務端txc的上下文
TxcContext.bind(xid,null);
//執行扣庫存操做
ret  = jdbcTemplate2.update("update stock set number = number -? where pid = ?",new Object[]{sk.getPnum(),sk.getPid()});
return ret;
}

3.7 GTS的應用狀況
GTS在知足事務ACID的前提下,普通配置的單服務器能夠達到15000 TPS以上的超強性能(兩個小時完成1億多筆業務)。目前已經在淘寶、天貓、阿里影業、淘票票、阿里媽媽、1688等阿里各業務系統普遍使用,經受了16年和17年兩年雙十一海量請求的考驗。某線上業務系統最高流量已達十萬TPS(每秒鐘10萬筆事務)。GTS在阿里雲及專有云上輸出後,有不少用戶經過GTS解決SpringCloud、Dubbo、Edas等微服務的分佈式事務問題,包括國家電網、中國郵政、中國菸草、特步、浙江公安、德邦快遞、一步共享科技等,涉及電力、物流、ETC、菸草、金融、零售、電商、共享出行等十幾個行業,獲得用戶的一致承認。
圖片描述
上圖是GTS與SpringCloud集成,應用於某共享出行系統。業務共享出行場景下,經過GTS支撐物聯網系統、訂單系統、支付系統、運維繫統、分析系統等系各統應用事務一致性,保證海量訂單和數千萬流水的交易。
原文連接

相關文章
相關標籤/搜索