項目說明
本項目演示如何使用 Fescar Starter 完成 Spring Cloud 應用的分布式事務接入。
准備工作
在運行此示例之前,你需要先完成如下幾步准備工作:
-
配置數據庫
-
創建 UNDO_LOG 表
-
創建 示例中 業務所需要的數據庫表
-
啟動 Fescar Server
配置數據庫
首先,你需要有一個支持 InnoDB 引擎的 MySQL 數據庫。
注意: 實際上,Fescar 支持不同的應用使用完全不相干的數據庫,但是這里為了簡單地演示一個原理,所以我們選擇了只使用一個數據庫。
將 account-server
、order-service
、storage-service
這三個應用中的 resources 目錄下的 application.properties
文件中的如下配置修改成你運行環境中的實際配置。
mysql.server.ip=your mysql server ip address
mysql.server.port=your mysql server listening port
mysql.db.name=your database name for test
mysql.user.name=your mysql server username
mysql.user.password=your mysql server password
創建 undo_log 表
Fescar AT 模式 需要使用到 undo_log 表。
-- 注意此處0.3.0+ 增加唯一索引 ux_undo_log
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
創建 示例中 業務所需要的數據庫表
DROP TABLE IF EXISTS `storage_tbl`;
CREATE TABLE `storage_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`commodity_code` varchar(255) DEFAULT NULL,
`count` int(11) DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY (`commodity_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `order_tbl`;
CREATE TABLE `order_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) DEFAULT NULL,
`commodity_code` varchar(255) DEFAULT NULL,
`count` int(11) DEFAULT 0,
`money` int(11) DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `account_tbl`;
CREATE TABLE `account_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) DEFAULT NULL,
`money` int(11) DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
啟動 Fescar Server
點擊這個頁面 https://github.com/alibaba/fescar/releases,下載最新版本的 Fescar Server 端.
進入解壓之后的 bin 目錄,執行如下命令來啟動
sh fescar-server.sh $LISTEN_PORT $PATH_FOR_PERSISTENT_DATA
在這個示例中,采用如下命令來啟動 Fescar Server
sh fescar-server.sh 8091 ~/fescar/data/
注意 如果你修改了端口號,那么記得需要在各個示例工程中的 application.conf
文件中,修改 grouplist 的值。
運行示例
分別運行 account-server
、order-service
、storage-service
和 business-service
這三個應用的 Main 函數,啟動示例。
啟動示例后,通過 HTTP 的 GET 方法訪問如下兩個 URL,可以分別驗證在 business-service
中 通過 RestTemplate 和 FeignClient 調用其他服務的場景。
http://127.0.0.1:18081/fescar/feign
http://127.0.0.1:18081/fescar/rest
如何驗證分布式事務成功?
Xid 信息是否成功傳遞
在 account-server
、order-service
和 storage-service
三個 服務的 Controller 中,第一個執行的邏輯都是輸出 RootContext 中的 Xid 信息,如果看到都輸出了正確的 Xid 信息,即每次都發生變化,且同一次調用中所有服務的 Xid 都一致。則表明 Fescar 的 Xid 的傳遞和還原是正常的。
數據庫中數據是否一致
在本示例中,我們模擬了一個用戶購買貨物的場景,StorageService 負責扣減庫存數量,OrderService 負責保存訂單,AccountService 負責扣減用戶賬戶余額。
為了演示樣例,我們在 OrderService 和 AccountService 中 使用 Random.nextBoolean() 的方式來隨機拋出異常,模擬了在服務調用時隨機發生異常的場景。
如果分布式事務生效的話, 那么以下等式應該成立
-
用戶原始金額(1000) = 用戶現存的金額 + 貨物單價 (2) * 訂單數量 * 每單的貨物數量(2)
-
貨物的初始數量(100) = 貨物的現存數量 + 訂單數量 * 每單的貨物數量(2)
對 Spring Cloud 支持點
-
通過 Spring MVC 提供服務的服務提供者,在收到 header 中含有 Fescar 信息的 HTTP 請求時,可以自動還原 Fescar 上下文。
-
支持服務調用者通過 RestTemplate 調用時,自動傳遞 Fescar 上下文。
-
支持服務調用者通過 FeignClient 調用時,自動傳遞 Fescar 上下文。
-
支持 FeignClient 和 Hystrix 同時使用的場景。
-
支持 FeignClient 和 Sentinel 同時使用的場景。