微服務架構下分布式事務解決方案 —— 阿里GTS

1 微服務的發展

微服務倡導將復雜的單體應用拆分為若干個功能簡單、松耦合的服務,這樣可以降低開發難度、增強擴展性、便于敏捷開發。當前被越來越多的開發者推崇,很多互聯網行業巨頭、開源社區等都開始了微服務的討論和實踐。Hailo有160個不同服務構成,NetFlix有大約600個服務。國內方面,阿里巴巴、騰訊、360、京東、58同城等很多互聯網公司都進行了微服務化實踐。當前微服務的開發框架也非常多,比較著名的有Dubbo、SpringCloud、thrift 、grpc等。

2 微服務落地存在的問題

雖然微服務現在如火如荼,但對其實踐其實仍處于探索階段。很多中小型互聯網公司,鑒于經驗、技術實力等問題,微服務落地比較困難。如著名架構師Chris Richardson所言,目前存在的主要困難有如下幾方面:

1)單體應用拆分為分布式系統后,進程間的通訊機制和故障處理措施變的更加復雜。

2)系統微服務化后,一個看似簡單的功能,內部可能需要調用多個服務并操作多個數據庫實現,服務調用的分布式事務問題變的非常突出。

3)微服務數量眾多,其測試、部署、監控等都變的更加困難。

隨著RPC框架的成熟,第一個問題已經逐漸得到解決。例如dubbo可以支持多種通訊協議,springcloud可以非常好的支持restful調用。對于第三個問題,隨著docker、devops技術的發展以及各公有云paas平臺自動化運維工具的推出,微服務的測試、部署與運維會變得越來越容易。

而對于第二個問題,現在還沒有通用方案很好的解決微服務產生的事務問題。分布式事務已經成為微服務落地最大的阻礙,也是最具挑戰性的一個技術難題。 為此,本文將深入和大家探討微服務架構下,分布式事務的各種解決方案,并重點為大家解讀阿里巴巴提出的分布式事務解決方案----GTS。該方案中提到的GTS是全新一代解決微服務問題的分布式事務互聯網中間件

3 傳統分布式事務解決方案

3.1 基于XA協議的兩階段提交方案

交易中間件與數據庫通過 XA 接口規范,使用兩階段提交來完成一個全局事務, XA 規范的基礎是兩階段提交協議。
第一階段是表決階段,所有參與者都將本事務能否成功的信息反饋發給協調者;第二階段是執行階段,協調者根據所有參與者的反饋,通知所有參與者,步調一致地在所有分支上提交或者回滾。

兩階段提交方案應用非常廣泛,幾乎所有商業OLTP數據庫都支持XA協議。但是兩階段提交方案鎖定資源時間長,對性能影響很大,基本不適合解決微服務事務問題。

3.2 TCC方案

TCC方案在電商、金融領域落地較多。TCC方案其實是兩階段提交的一種改進。其將整個業務邏輯的每個分支顯式的分成了Try、Confirm、Cancel三個操作。Try部分完成業務的準備工作,confirm部分完成業務的提交,cancel部分完成事務的回滾。基本原理如下圖所示。

事務開始時,業務應用會向事務協調器注冊啟動事務。之后業務應用會調用所有服務的try接口,完成一階段準備。之后事務協調器會根據try接口返回情況,決定調用confirm接口或者cancel接口。如果接口調用失敗,會進行重試。

TCC方案讓應用自己定義數據庫操作的粒度,使得降低鎖沖突、提高吞吐量成為可能。 當然TCC方案也有不足之處,集中表現在以下兩個方面:

  • 對應用的侵入性強。業務邏輯的每個分支都需要實現try、confirm、cancel三個操作,應用侵入性較強,改造成本高。
  • 實現難度較大。需要按照網絡狀態、系統故障等不同的失敗原因實現不同的回滾策略。為了滿足一致性的要求,confirm和cancel接口必須實現冪等。

上述原因導致TCC方案大多被研發實力較強、有迫切需求的大公司所采用。微服務倡導服務的輕量化、易部署,而TCC方案中很多事務的處理邏輯需要應用自己編碼實現,復雜且開發量大。

3.3 基于消息的最終一致性方案

消息一致性方案是通過消息中間件保證上、下游應用數據操作的一致性。基本思路是將本地操作和發送消息放在一個事務中,保證本地操作和消息發送要么兩者都成功或者都失敗。下游應用向消息系統訂閱該消息,收到消息后執行相應操作。

消息方案從本質上講是將分布式事務轉換為兩個本地事務,然后依靠下游業務的重試機制達到最終一致性。基于消息的最終一致性方案對應用侵入性也很高,應用需要進行大量業務改造,成本較高。

4 GTS--分布式事務解決方案

GTS是一款分布式事務中間件,由阿里巴巴中間件部門研發,可以為微服務架構中的分布式事務提供一站式解決方案。

更多GTS資料請訪問研發團隊微博。

4.1 GTS的核心優勢

  • 性能超強

GTS通過大量創新,解決了事務ACID特性與高性能、高可用、低侵入不可兼得的問題。單事務分支的平均響應時間在2ms左右,3臺服務器組成的集群可以支撐3萬TPS以上的分布式事務請求。

  • 應用侵入性極低

GTS對業務低侵入,業務代碼最少只需要添加一行注解(@TxcTransaction)聲明事務即可。業務與事務分離,將微服務從事務中解放出來,微服務關注于業務本身,不再需要考慮反向接口、冪等、回滾策略等復雜問題,極大降低了微服務開發的難度與工作量。

  • 完整解決方案

GTS支持多種主流的服務框架,包括EDAS,Dubbo,Spring Cloud等。
有些情況下,應用需要調用第三方系統的接口,而第三方系統沒有接入GTS。此時需要用到GTS的MT模式。GTS的MT模式可以等價于TCC模式,用戶可以根據自身業務需求自定義每個事務階段的具體行為。MT模式提供了更多的靈活性,可能性,以達到特殊場景下的自定義優化及特殊功能的實現。

  • 容錯能力強

GTS解決了XA事務協調器單點問題,實現真正的高可用,可以保證各種異常情況下的嚴格數據一致。

4.2 GTS的應用場景

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

4.3 GTS與微服務的集成

GTS包括客戶端(GTS Client)、資源管理器(GTS RM)和事務協調器(GTS Server)三個部分。GTS Client主要用來界定事務邊界,完成事務的發起與結束。GTS RM完成事務分支的創建、提交、回滾等操作。GTS Server主要負責分布式事務的整體推進,事務生命周期的管理。GTS和微服務集成的結構圖如下所示,GTS Client需要和業務應用集成部署,RM與微服務集成部署。

4.4 GTS的輸出形式

GTS目前有三種輸出形式:公有云輸出、公網輸出、專有云輸出。

4.4.1 公有云輸出

這種輸出形式面向阿里云用戶。如果用戶的業務系統已經部署到阿里云上,可以申請開通公有云GTS。開通后業務應用即可通過GTS保證服務調用的一致性。這種使用場景下,業務系統和GTS間的網絡環境比較理想,達到很好性能。

4.4.2 公網輸出

這種輸出形式面向于非阿里云的用戶,使用更加方便、靈活,業務系統只要能連接互聯網即可享受GTS提供的云服務(與公有云輸出的差別在于客戶端部署于用戶本地,而不在云上)。

在正常網絡環境下,以包含兩個本地事務的全局事務為例,事務完成時間在20ms左右,50個并發就可以輕松實現1000TPS以上分布式事務,對絕大多數業務來說性能是足夠的。在公網環境,網絡閃斷很難完全避免,這種情況下GTS仍能保證服務調用的數據一致性。

具體使用樣例使用參見4.7節GTS的工程樣例。

4.4.3 專有云輸出

這種形式主要面向于已建設了自己專有云平臺的大用戶,GTS可以直接部署到用戶的專有云上,為專有云提供分布式事務服務。目前已經有10多個特大型企業的專有云使用GTS解決分布式事務難題,性能與穩定性經過了用戶的嚴格檢測。

4.5 GTS的使用方式

GTS對應用的侵入性非常低,使用也很簡單。下面以訂單存儲應用為例說明。訂單業務應用通過調用訂單服務和庫存服務完成訂單業務,服務開發框架為Dubbo。

4.5.1 訂單業務應用

在業務函數外圍使用@TxcTransaction注解即可開啟分布式事務。Dubbo應用通過隱藏參數將GTS的事務xid傳播到服務端。

@TxcTransaction(timeout = 1000 * 10)
public void Bussiness(OrderService orderService, StockService stockService, String userId) {
//獲取事務上下文
String xid = TxcContext.getCurrentXid();
//通過RpcContext將xid傳到一個服務端
RpcContext.getContext().setAttachment("xid", xid);//執行自己的業務邏輯
int productId = new Random().nextInt(100);
int productNum = new Random().nextInt(100);
OrderDO orderDO = new OrderDO(userId, productId, productNum, new Timestamp(new Date().getTime()));
orderService.createOrder(orderDO);//通過RpcContext將xid傳到另一個服務端
RpcContext.getContext().setAttachment("xid",xid);
stockService.updateStock(orderDO);

}

4.5.2 服務提供者

更新庫存方法


public int updateStock(OrderDO orderDO) {
//獲取全局事務ID,并綁定到上下文
String xid = RpcContext.getContext().getAttachment("xid");
TxcContext.bind(xid,null);
//執行自己的業務邏輯
int ret = jdbcTemplate.update("update stock set amount = amount - ? where product_id = ?",new Object[]{orderDO.getNumber(), orderDO.getProductId()});
TxcContext.unbind();
return ret;

}

4.6 GTS的應用情況

GTS目前已經在淘寶、天貓、阿里影業、淘票票、阿里媽媽、1688等阿里各業務系統廣泛使用,經受了16年和17年兩年雙十一海量請求的考驗。某線上業務系統最高流量已達十萬TPS(每秒鐘10萬筆事務)。

GTS在公有云和專有云輸出后,已經有了100多個線上用戶,很多用戶通過GTS解決SpringCloud、Dubbo、Edas等服務框架的分布式事務問題。業務領域涉及電力、物流、ETC、煙草、金融、零售、電商、共享出行等十幾個行業,得到用戶的一致認可。

上圖是GTS與SpringCloud集成,應用于某共享出行系統。業務共享出行場景下,通過GTS支撐物聯網系統、訂單系統、支付系統、運維系統、分析系統等系各統應用的數據一致性,保證海量訂單和數千萬流水的交易。

4.7 GTS的工程樣例

GTS的公有云樣例可參考阿里云網站。在公網環境下提供sample-txc-simple和sample-txc-dubbo兩個樣例工程。

4.7.1 sample-txc-simple樣例

4.7.1.1 樣例業務邏輯

該樣例是GTS的入門sample,案例的業務邏輯是從A賬戶轉賬給B賬戶,其中A和B分別位于兩個MySQL數據庫中,使用GTS事務保證A和B賬戶錢的總數始終不變。

4.7.1.2 樣例搭建方法

1) 準備數據庫環境

安裝MySQL,創建兩個數據庫db1和db2。在db1和db2中分別創建txc_undo_log表(SQL腳本見4.7.3)。在db1庫中創建user_money_a表,在db2庫中創建user_money_b表。

2) 下載樣例

將sample-txc-simple文件下載到本地,樣例中已經包含了GTS的SDK。

3) 修改配置

打開sample-txc-simple/src/main/resources目錄下的txc-client-context.xml,將數據源的url、username、password修改為實際值。

4) 運行樣例

在sample-txc-simple目錄下執行build.sh編譯本工程。編譯完成后執行run.sh。

4.7.2 sample-txc-dubbo 樣例

4.7.2.1 樣例業務邏輯

本案例模擬了用戶下訂單、減庫存的業務邏輯。客戶端(Client)通過調用訂單服務(OrderService)創建訂單,之后通過調用庫存服務(StockService)扣庫存。其中訂單服務讀寫訂單數據庫,庫存服務讀寫庫存數據庫。由 GTS 保證跨服務事務的一致性。

4.7.2.2 樣例搭建方法

1) 準備數據庫環境

安裝MySQL,創建兩個數據庫db1和db2。在db1和db2中分別創建txc_undo_log表。在db1庫中創建orders表,在db2庫中創建stock表。

2) 下載樣例

將樣例文件sample-txc-dubbo下載到本地機器,樣例中已經包含了GTS的SDK。

3) 修改配置

打開sample-txc-dubbo/src/main/resources目錄,將dubbo-order-service.xml、dubbo-stock-service.xml兩個文件中數據源的url、username、password修改為實際值。

4) 運行樣例

  1. 編譯程序

    在工程根目錄執行 build.sh 命令,編譯工程。編譯后會在 sample-txc-dubbo/client/bin 目錄下生成 order_run.sh、stock_run.sh、client_run.sh 三個運行腳本對應訂單服務、庫存服務以及客戶端。

  2. 運行程序

    在根目錄執行run.sh,該腳本會依次啟動order_run.sh(訂單服務)、stock_run.sh(庫存服務)和client_run.sh(客戶端程序)。

4.7.2.3 其他說明

樣例使用Multicast注冊中心的聲明方式。如果本機使用無線網絡,dubbo服務在綁定地址時有可能獲取ipv6地址,可以通過jvm啟動參數禁用。
方法是配置jvm啟動參數 -Djava.net.preferIPv4Stack=true

4.7.3 SQL

4.7.3.1 建表 txc_undo_log

CREATE TABLE txc_undo_log (

id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',

gmt_create datetime NOT NULL COMMENT '創建時間',

gmt_modified datetime NOT NULL COMMENT '修改時間',

xid varchar(100) NOT NULL COMMENT '全局事務ID',

branch_id bigint(20) NOT NULL COMMENT '分支事務ID',

rollback_info longblob NOT NULL COMMENT 'LOG',

status int(11) NOT NULL COMMENT '狀態',

server varchar(32) NOT NULL COMMENT '分支所在DB IP',

PRIMARY KEY (id),

KEY unionkey (xid,branch_id)

) ENGINE=InnoDB AUTO_INCREMENT=211225994 DEFAULT CHARSET=utf8 COMMENT='事務日志表';

4.7.3.2 建表 user_money_a

CREATE TABLE user_money_a (

id int(11) NOT NULL AUTO_INCREMENT,

money int(11) DEFAULT NULL,

PRIMARY KEY (id)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

4.7.3.3 建表 user_money_b

CREATE TABLE user_money_b (

id int(11) NOT NULL AUTO_INCREMENT,

money int(11) DEFAULT NULL,

PRIMARY KEY (id)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

4.7.3.4 建表 orders

CREATE TABLE orders (

id bigint(20) NOT NULL AUTO_INCREMENT,

user_id varchar(255) NOT NULL,

product_id int(11) NOT NULL,

number int(11) NOT NULL,

gmt_create timestamp NOT NULL,

PRIMARY KEY (id)

) ENGINE=MyISAM AUTO_INCREMENT=351 DEFAULT CHARSET=utf8

4.7.3.5 建表 stock

CREATE TABLE stock (

product_id int(11) NOT NULL,

price float NOT NULL,

amount int(11) NOT NULL,

PRIMARY KEY (product_id)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

5 總結

GTS已經在阿里內部廣泛使用,經過了雙十一流量高峰的考驗。內部成熟后,在專有云和公有云服務了很多用戶,很多用戶一天事務量在千萬/億級別,解決了業務服務化改造后的分布式事務棘手技術難題。

在整個世界范圍內,既滿足事務ACID特性,又具備高性能、高可用、業務侵入性低的分布式事務中間件在GTS前是不存在的。讓我們一起體驗GTS帶來的巨大變革吧!

想了解更多GTS信息,可以參考以下內容:

  • GTS(TXC)官網
  • 研發團隊微博

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/283881.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/283881.shtml
英文地址,請注明出處:http://en.pswp.cn/news/283881.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

重要消息丨.NET Core 3.1 將于今年12月13日結束支持

點擊上方藍字關注我們(本文閱讀時間:5分鐘).NET Core 3.1 將于 2022 年 12 月 13 日結束支持。此后,Microsoft 將不再為 .NET Core 3.1 提供服務更新或技術支持。我們建議盡快遷移到 .NET 6。如果您在支持日期結束后仍在使用 .NET Core 3.1&a…

產品設計的三大原則

1.它有用嗎? 如果我們必須從這三個特性中選擇一個作為最重要的,那就是有用性。 首要的是,一個產品必須有用。如果它無用,其它任何東西都是不相關的,因為沒有人會需要它。很明顯,有用性和可享用性看上去一樣重要&#…

常用的17個運維監控系統

1. Zabbix Zabbix 作為企業級的網絡監控工具,通過從服務器,虛擬機和網絡設備收集的數據提供實時監控,自動發現,映射和可擴展等功能。 Zabbix的企業級監控軟件為用戶提供內置的Java應用服務器監控,硬件監控&#xff0c…

關于html-三角的制作

因為最近看到別人寫的不錯的樣式,所以就想自己實現,但是呢用到了一個三角形,所以稍微研究一下。效果是這樣的:注意是下邊那個淺色三角,感覺書簽的效果有木有。看著很有層次感。接下來就是實現了,利用border…

ABP中的數據過濾器

本文首先介紹了ABP內置的軟刪除過濾器(ISoftDelete)和多租戶過濾器(IMultiTenant),然后介紹了如何實現一個自定義過濾器,最后介紹了在軟件開發過程中遇到的實際問題,同時給出了解決問題的一個未必最優的思路。一.預定義過濾器ABP中的數據過濾…

ActiveMQ與spring整合

2019獨角獸企業重金招聘Python工程師標準>>> 1 生產者 第一步&#xff1a;引用相關的jar包。 <dependency> <groupId>org.springframework</groupId><artifactId>spring-jms</artifactId> </dependency> <dependency><…

最新遠程部署運維工具匯總

一&#xff0e;Puppet 轉載https://baike.baidu.com/item/puppet/5109503?fraladdin puppet是一種Linux、Unix、windows平臺的集中配置管理系統&#xff0c;使用自有的puppet描述語言&#xff0c;可管理配置文件、用戶、cron任務、軟件包、系統服務等。puppet把這些系統實體…

Kali Linux 2016.2初體驗使用總結

Kali Linux 2016.2初體驗使用總結Kali Linux官方于8月30日發布Kali Linux 2016的第二個版本Kali Linux 2016.2。該版本距離Kali Linux 2016.1版本發布&#xff0c;已經有7個月。在這期間&#xff0c;在Kali Linux 2016.2版本發布的這段時間&#xff0c;Kali Linux官方增補了94個…

Kafka入門教程:學習總結目錄索引

【Kafka】| 總結/Edison ZhouEdison總結了Kafka的學習征途系列&#xff0c;特意整理了一份目錄索引&#xff0c;希望對你有幫助。0Kafka學習路徑在學習Kafka的途中&#xff0c;我總結了一個系列的Kafka學習征途系列教程&#xff0c;它只選取了我認為最實用的部分整理出來&#…

javaweb學習中的路徑問題

1. 項目結構 2. 客戶端路徑 1. 超鏈接 <% page language"java" contentType"text/html; charsetUTF-8"pageEncoding"UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/…

步步為營-11-ListT泛型的簡單練習

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 集合簡單練習 {class Program{static void Main(string[] args){}private static void Test3(){//奇偶分揀,奇數在前偶數在后List<int>…

SPI 與 API的區別

背景 Java 中區分 API 和 SPI&#xff0c;通俗的講&#xff1a;API 和 SPI 都是相對的概念&#xff0c;他們的差別只在語義上&#xff0c;API 直接被應用開發人員使用&#xff0c;SPI 被框架擴展人員使用 理解 API &#xff08;Application Programming Interface&#xff09; …

JS---------正則表達式

2019獨角獸企業重金招聘Python工程師標準>>> 1.正則表達式的創建方式&#xff1a; 1.1 var reg new RegExp(pattern); 1.2 var reg /^正則規則$/ 2.正則規則&#xff1a; 2.1 [0-9] 代表數字 [A-Z] 代表大寫字母 [a-z] 代表小寫字母 [A-z] 代表字母 \w 查找單詞字…

關于緩存異常:緩存雪崩、擊穿、穿透的解決方案

關于緩存雪崩、擊穿、穿透的解決方案 前言緩存雪崩 緩存雪崩的原因解決方案緩存擊穿 解決方案緩存穿透 解決方案 布隆過濾器 布隆過濾器原理布隆過濾器如何使用在Java中使用布隆過濾器前言 關于緩存異常&#xff0c;我們常見的有三個問題&#xff1a;緩存雪崩、緩存擊穿、緩存穿…

RobotFramework 自動化測試實戰進階篇

工具 Robotframework, 采用PO設計模式 PO模型 PO模型即Page Objects&#xff0c;直譯意思就是“頁面對象”&#xff0c;通俗的講就是把一個頁面&#xff0c;或者說把一個頁面的某個區域當做一個對象&#xff0c;通過封裝這個對象可以實現調用。 PO設計的好處 代碼復用&…

Android6 0權限機制(一):介紹

本篇文章已授權微信公眾號 hongyangAndroid &#xff08;鴻洋&#xff09;獨家發布 Android6.0權限機制&#xff08;一&#xff09;&#xff1a;介紹 Android6.0權限機制&#xff08;二&#xff09;&#xff1a;封裝 Android6.0權限機制&#xff08;三&#xff09;&#xff1a;…

MAX10 ADC的一些基知識

MAX10 ADC 的一些知識 1、 MAX 10 內部集成的12bit SAR ADC的特點為&#xff1a; a、 采樣速率高達1Mhz. b、 模擬通道多達18個&#xff0c;單個ADC多達17個&#xff0c;雙ADC器件中有16個雙功能ADC通道&#xff0c;2個專用的ADC。 c、 提供單端測…

Blazor University (42)JavaScript 互操作 —— 生命周期和內存泄漏

原文鏈接&#xff1a;https://blazor-university.com/javascript-interop/calling-dotnet-from-javascript/lifetimes-and-memory-leaks/生命周期和內存泄漏源代碼[1]如果我們運行我們在從 Javascript 調用 .NET 中創建的應用程序并檢查瀏覽器控制臺窗口&#xff0c;我們會看到…

深入淺出聊布隆過濾器(Bloom Filter)

之前在網上看到過這么一段話&#x1f447; Data structures are nothing different. They are like the bookshelves of your application where you can organize your data. Different data structures will give you different facility and benefits. To properly use the …

第五周作業

本周作業內容&#xff1a;顯示當前系統上root、fedora或user1用戶的默認shell&#xff1b;#egrep "^(root|user1|fedora)" /etc/passwd|cut -d: -f72、找出/etc/rc.d/init.d/functions文件中某單詞后面跟一組小括號的行&#xff0c;形如&#xff1a;hello()&#xff…