基于seata官網示例改造的最新版本 Spring Cloud Alibaba + OpenFeign + Druid + Seata 分布式事務演練
- 環境準備
- seata
- seata 是什么
- seata 特色功能
- 快速開始
- 用例
- 架構圖
- 專案模塊
- 安裝seata
- 解壓seata-server-1.4.rar
- 修改注冊中心組態檔 /seata/conf/reigstry.conf
- 修改seata-server 事務日志配置 seata/conf/file.conf,sql腳本在專案的doc檔案seata.sql
- 添加seata配置引數到nacos
- 啟動
- 測驗案例
- 遇到一些坑
- 版本依賴過低
- 專案中使用druid 自動配置依賴
本專案案例基于seata官網快速開始示例改造,官方展示的是Dubbo + SEATA提供支持的示例,本人基于此示例整合Spring Cloud Alibaba + OpenFeign + Druid + Seata ,
環境準備
本案例版本是 Spring Cloud Alibaba 2.2.1.RELEASE + Spring Boot 2.2.2 RELEASE
- 下載nacos,用于微服務的注冊和配置中心,seata是一個分布式事務服務,可以把seata服務注冊到nacos,seata的配置引數,可以保持在nacos上,
- 下載seata-server-1.4.0,seata-server其實就是TC(分布式事務協調器)
- 初始化sql陳述句,并下載專案,原始碼地址 https://gitee.com/brozer/alibaba-seata-samples
seata
seata 是什么
Seata 是一款開源的分布式事務解決方案,致力于在微服務架構下提供高性能和簡單易用的分布式事務服務,在 Seata 開源之前,Seata 對應的內部版本在阿里經濟體內部一直扮演著分布式一致性中間件的角色,幫助經濟體平穩的度過歷年的雙11,對各BU業務進行了有力的支撐,經過多年沉淀與積累,商業化產品先后在阿里云、金融云進行售賣,2019.1 為了打造更加完善的技術生態和貧訓技術成果,Seata 正式宣布對外開源,未來 Seata 將以社區共建的形式幫助其技術更加可靠與完備,
seata 特色功能
- 微服務框架支持
目前已支持 Dubbo、Spring Cloud、Sofa-RPC、Motan 和 grpc 等RPC框架,其他框架持續集成中 - AT模式
提供無侵入自動補償的事務模式,目前已支持 MySQL、 Oracle 、PostgreSQL和 TiDB的AT模式,H2 開發中 - TCC模式
支持 TCC 模式并可與 AT 混用,靈活度更高 - SAGA 模式
為長事務提供有效的解決方案 - XA 模式
支持已實作 XA 介面的資料庫的 XA 模式 - 高可用
支持基于資料庫存盤的集群模式,水平擴展能力強
快速開始
用例
用戶購買商品的業務邏輯,整個業務邏輯由3個微服務提供支持:
- 倉儲服務:對給定的商品扣除倉儲數量,
- 訂單服務:根據采購需求創建訂單,
- 帳戶服務:從用戶帳戶中扣除余額,
架構圖

專案模塊
本案例是個maven聚合工程,總共有5個模塊,
- samples-common-service 公共依賴服務,定義了一些公共基礎類和OpenFeign介面定義,
- samples-account-service 賬戶服務,賬號服務提供者
- samples-business-service 業務服務,用于接受用戶請求,處理業務邏輯,微服務消費者,
- samples-order-service 訂單服務,根據采購需求創建訂單,訂單服務提供者,賬號服務消費者,
- samples-storage-service 存盤服務,給指定商品扣除倉儲數量,存盤服務提供者,

安裝seata
解壓seata-server-1.4.rar
修改注冊中心組態檔 /seata/conf/reigstry.conf
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
loadBalance = "RandomLoadBalance"
loadBalanceVirtualNodes = 10
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = ""
cluster = "default"
username = "nacos"
password = "nacos"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = ""
group = "SEATA_GROUP"
username = "nacos"
password = "nacos"
}
}
修改seata-server 事務日志配置 seata/conf/file.conf,sql腳本在專案的doc檔案seata.sql
## transaction log store, only used in seata-server
store {
## store mode: file、db、redis
mode = "db"
## database store property
db {
## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc.
datasource = "druid"
## mysql/oracle/postgresql/h2/oceanbase etc.
dbType = "mysql"
driverClassName = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://127.0.0.1:3306/seata?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true"
user = "root"
password = "123456"
minConn = 5
maxConn = 100
globalTable = "global_table"
branchTable = "branch_table"
lockTable = "lock_table"
queryLimit = 100
maxWait = 5000
}
}
配置好后,啟動seata-server服務,查看seata服務是否注冊到Nacos了

添加seata配置引數到nacos
上一步驟啟動只是驗證seata-server是否注冊到nacos中,由于我們的配置也保持在了nacos中,所以需要在nacos中添加seata的配置引數,為了避免一個個添加,官方為我們提供了config.txt(我拷貝到了seata/conf/config.txt) 組態檔和啟動腳本nacos-config.sh(拷貝到了seata/conf/nacos/nacos-config.sh),
我們需要修改config.txt
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableClientBatchSendRequest=false
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3
#修改my_test_tx_group為自定義服務seata-group
service.vgroupMapping.seata-group=default
service.default.grouplist=127.0.0.1:8091
service.enableDegrade=false
service.disableGlobalTransaction=false
client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=false
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
store.mode=db
store.file.dir=file_store/data
store.file.maxBranchSessionSize=16384
store.file.maxGlobalSessionSize=512
store.file.fileWriteBufferCacheSize=16384
store.file.flushDiskMode=async
store.file.sessionReloadReadSize=100
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true
store.db.user=root
store.db.password=123456
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
store.redis.host=127.0.0.1
store.redis.port=6379
store.redis.maxConn=10
store.redis.minConn=1
store.redis.database=0
store.redis.password=null
store.redis.queryLimit=100
server.recovery.committingRetryPeriod=1000
server.recovery.asynCommittingRetryPeriod=1000
server.recovery.rollbackingRetryPeriod=1000
server.recovery.timeoutRetryPeriod=1000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
client.undo.logTable=undo_log
client.log.exceptionRate=100
transport.serialization=seata
transport.compressor=none
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898
配置引數service.vgroupMapping.seata-group=default的seata-group需要和專案的 seata.tx-service-group一致,seata-server事務存盤我們保持到mysql,
執行啟動腳本nacos-config.sh,
./nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -u nacos -w nacos
至此,您可以在nacos配置串列中看到seata的配置引數了,如下圖所示

啟動
- 啟動nacos服務,
- 啟動seata-server
- 下載原始碼后,依次啟動 samples-account-service、samples-order-service、samples-storage-service、samples-business-service服務,
啟動看到如下圖所示,則表示微服務的資料源已被seata代理,微服務已經連上seata服務了,

測驗案例
請求鏈接因為專案是基于官網示例,沒有改,哈哈~
第一個介面是正常請求的,發現資料庫生成了相關記錄,
第二個介面時測驗例外的流程,事務回滾了,參與的事務分支在第二階段執行回滾操作,
遇到一些坑
版本依賴過低
因為使用版本過低,報:no available service ‘default’ found, please make sure registry config correct 錯誤,
這個錯誤資訊困擾我一個晚上了,最后看了原始碼,發現原始碼的配置引數少了很多,于是懷疑是否版本太舊不支持,果真換了版本就可以了,
seata-spring-boot-starter 默認采用的是1.1.0,需要替換成1.4.0,專案maven pom.xml檔案如下:
<!--alibaba seata start-->
<dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-seata -->
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<!--alibaba seata end-->
<dependency>
<groupId>com.example.cloud.alibaba</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.4.0</version>
<exclusions>
<exclusion>
<artifactId>asm</artifactId>
<groupId>org.ow2.asm</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>8.0.1</version>
</dependency>
專案中使用druid 自動配置依賴
使用druid-spring-boot-starter配置,會導致報錯 xxx …com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceWrapper$$Enhancer
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
解決方法:去掉依賴,然后自己在專案配置druid引數配置,配置成功如下圖所示

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/252660.html
標籤:其他
上一篇:Android 開發年前刷題500+,仍遭位元組面試官慘拒!直言道:不要“不懂原理”的刷題機器
下一篇:Redis集群方案
