マイクロサービスのアーキテクチャの下で分散トランザクションソリューションズ - アリGTS
1マイクロ開発サービス
サービスの複雑なマイクロは、開発努力、アジャイルのための強化された拡張性を減らすことができ、いくつかの単純な関数、疎結合サービスへのモノマーのアプリケーション分割を提唱しました。現在、より多くの開発者は、多くのインターネット業界の巨人、オープンソース・コミュニティを尊敬しているので、マイクロサービスの議論と実践を始めました。Hailo 160異なるサービス構成、Netflixの約600のサービス。国内では、アリババ、テンセント、360、Jingdongは、58都市、および他の多くのインターネット企業は、マイクロサービスの練習を行いました。マイクロサービスの開発のための現在のフレームワークは、非常に大きい比較的よく知られているダボ、SpringCloud、倹約 、GRPCなど。
2マイクロサービス着陸問題
マイクロサービスが本格的になりましたが、その実践は、探索段階ではまだ実際にではあるが。多くの中小インターネット企業、経験、技術力やその他の問題、より困難なマイクロサービス着陸の点で好ましいです。:そのようなクリス・リチャードソンが言った有名な建築家、側面を、以下の主な既存の難しさなど
分散システムのための1)のモノマーの分割アプリケーションの後に、プロセス間通信機構とトラブル対策がより複雑になります。
マイクロサービス、一見単純な機能の2)システムの後、複数のデータベースを達成するために、複数の内部サービスやオペレーションを呼び出す必要があり、分散トランザクションサービス呼び出しの問題は非常に顕著になります。
3)マイクロサービス、そのテスト、展開、および監視の多数は、より困難になります。
RPCフレームワークの成熟度では、最初の問題は徐々に解決されました。例えば、ダボは、複数の通信プロトコルをサポートすることができ、springcloudは非常に良いサポート安らか通話することができます。第三の問題については、ドッキングウィンドウの導入により、開発がますます容易になるだろう技術だけでなく、パブリッククラウドのPaaSプラットフォームの動作および自動化ツール、マイクロサービスのテスト、展開、運用・保守のメンテナンスをDevOpsチーム。
2番目の質問については、発生する一般的スキームのマイクロトランザクションサービスの問題への良い解決策はありません。分散トランザクションは、最大のマイクロサービスを着陸への障害となっている、また最も困難である技術的な問題。本稿では、深さを探求し、マイクロサービスアーキテクチャの下で、分散トランザクション・ソリューション、および我々は分散トランザクションソリューションを解釈するよう注力---- GTSアリババが上昇しました。プログラムに記載されたGTSは、分散トランザクションのインターネットミドルウェアの問題を解決するための全く新しい世代のマイクロサービスです。
3 SOA分散トランザクションソリューションズ
3.1著者スキームは二相XAプロトコルに基づいています
二相を用いたインタフェース仕様を介してXAトランザクション・ミドルウェアとデータベースは、グローバル・トランザクションを完了するためにコミット、XA仕様は、二相の基礎がコミットプロトコルです。
一斉に全ての参加者に通知し、第二段階は、実装段階、すべての参加者からのフィードバックのコーディネーターであり、第一段階は、すべての参加者が、コーディネータに送信されるフィードバックの成功に取引に関する情報を提示する、投票相でありますすべてのブランチがコミットまたはロールバック。
二相は、スキームが広く使用されているほぼすべての商用OLTPデータベースのサポートXAプロトコルをコミット。しかし、二相は、長い時間のためのリソースのロック・スキーム、マイクロトランザクションサービスの基本的な問題を解決するのに適していないのパフォーマンスに大きな影響を与え、コミット。
3.2 TCCプログラム
TCCプログラムは、電気事業に多くの金融セクターを上陸させました。TCCプログラムは、実際に改善2フェーズ・コミットです。3つの操作をキャンセルしてみてくださいに明示的に全体のビジネスロジック、確認し、各ブランチ。、準備作業のビジネスの一部を完了し提出する事業の一部の完了を確認してみてください、バック完全なロールトランザクションの一部を取り消します。図に示すように、基本的な原理。
トランザクションが開始されると、ビジネスアプリケーションは、トランザクションコーディネータに登録されたトランザクションを開始します。後のビジネス・アプリケーションは、準備の段階を完了しようとするすべてのサービス・インターフェースを呼び出します。コーディネーターは、インターフェイスよる試みに戻りますトランザクションの後、我々はインターフェイスのインターフェイスを確認またはキャンセルするために呼び出すことにしました。インタフェースの呼び出しが失敗した場合、それが再試行されます。
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) 运行样例
a. 编译程序
在工程根目录执行 build.sh 命令,编译工程。编译后会在 sample-txc-dubbo/client/bin 目录下生成 order_run.sh、stock_run.sh、client_run.sh 三个运行脚本对应订单服务、库存服务以及客户端。
b. 运行程序
在根目录执行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テーブルの注文を構築
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
タイムスタンプのNOT NULL、
PRIMARY KEY( id
)
)ENGINE = MyISAMのAUTO_INCREMENT = 351 DEFAULT CHARSET = UTF8
4.7.3.5テーブルの株式のビルド
CREATE TABLEを stock
(
product_id
INT(11)NOT NULLと、
price
、NOT NULLをフロート
amount
INT(11)NOT NULLと、
PRIMARY KEY( product_id
)
)ENGINE =のInnoDB DEFAULT CHARSET = utf8を