前言
最近升级了我的开源项目的SpringCloudAlibaba版本(2.2.3.RELEASE)后,项目启动报了一堆错。后来一步一坑的解决,所以此处记录下,希望能帮助到和我一样升级遇到一堆坑的小伙伴。
升级前使用版本:
spring-boot:2.2.6.RELEASE;
spring-cloud:Hoxton.SR1;
spring-cloud-alibaba:.2.2.0.RELEASE;
前因
有一个小伙伴私信我说,我的开源项目中seata没法用,一开始我没在意,因为整合每个组件我都会测试ok后才会push代码的。后来他贴了一张截图给我,自己测试之后确实存在问题(无情打脸)。
异常如下:
NoSuchMethodError:com.alibaba.druid.sql.SQLUtils#parseStatements(java.lang.String,java.lang.String)
后来发现是因为自己指定了nacos-client版本为 1.2.0导致。
指定nacos-client版本为 1.2.0是为了解决异常:
java.net.ConnectException: no available server, currentServerAddr : http://xxx:8848
参考文章:https://blog.csdn.net/Thinkingcao/article/details/105505537
没想到会影响到seata的使用。索性就去除版本指定,然后升级spring-cloud-alibaba的版本2.2.3.RELEASE,因为其组件版本如下,符合我们的要求:
版本关系
升级后,启动报错(此处错误就不贴了,一堆堆栈),后来通过同步升级SpringCloud、springboot版本解决。
升级后使用版本:
spring-boot:2.3.2.RELEASE;
spring-cloud:Hoxton.SR8;
spring-cloud-alibaba:.2.2.3.RELEASE;
具体版本关系参照:
https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
spribgboot升级后,javax.validation.constraints下的注解都无法使用。
原因是springboot2.3.0版本后不包含validation包,需要手动引入。
1 2 3 4 5 | <!--validation 2.3.0版本后需要手动引入--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> |
seata服务端升级
虽然服务可以正常启动,但是seata还是报错:
no available service ‘default’ found, please make sure registry config correct
后来发现自己用的seata 服务端竟然还是 0.9.0 的版本,此版本不建议在生产环境使用。需要升级seata服务端版本,我是直接升级到了1.3.0版本。
使用Docker安装,Nacos作为配置和注册中心,Mysql作为存储库。
- 将seata服务端配置放到Nacos 上
1.准备config.txt和nacos-config.sh脚本。
config.txt文件内容如下,调整store.mode为db,并修改store.db相关配置。
service.vgroup-mapping.xxx-tx-group配置需要和项目中配置相同,下文会讲到。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | 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 service.vgroupMapping.my_test_tx_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.jdbc.Driver store.db.url=jdbc:mysql://111.231.111.150:3306/seata?useUnicode=true store.db.user=root store.db.password=gourd123 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.vgroup-mapping.sub-tx-group=default service.vgroup-mapping.admin-tx-group=default |
nacos-config.sh脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | while getopts ":h:p:g:t:u:w:" opt do case $opt in h) host=$OPTARG ;; p) port=$OPTARG ;; g) group=$OPTARG ;; t) tenant=$OPTARG ;; u) username=$OPTARG ;; w) password=$OPTARG ;; ?) echo " USAGE OPTION: $0 [-h host] [-p port] [-g group] [-t tenant] [-u username] [-w password] " exit 1 ;; esac done if [[ -z ${<!-- -->host} ]]; then host=localhost fi if [[ -z ${<!-- -->port} ]]; then port=8848 fi if [[ -z ${<!-- -->group} ]]; then group="SEATA_GROUP" fi if [[ -z ${<!-- -->tenant} ]]; then tenant="" fi if [[ -z ${<!-- -->username} ]]; then username="" fi if [[ -z ${<!-- -->password} ]]; then password="" fi nacosAddr=$host:$port contentType="content-type:application/json;charset=UTF-8" echo "set nacosAddr=$nacosAddr" echo "set group=$group" failCount=0 tempLog=$(mktemp -u) function addConfig() {<!-- --> curl -X POST -H "${contentType}" "http://$nacosAddr/nacos/v1/cs/configs?dataId=$1&group=$group&content=$2&tenant=$tenant&username=$username&password=$password" >"${tempLog}" 2>/dev/null if [[ -z $(cat "${tempLog}") ]]; then echo " Please check the cluster status. " exit 1 fi if [[ $(cat "${tempLog}") =~ "true" ]]; then echo "Set $1=$2 successfully " else echo "Set $1=$2 failure " (( failCount++ )) fi } count=0 for line in $(cat config.txt | sed s/[[:space:]]//g); do (( count++ )) key=${<!-- -->line%%=*} value=${<!-- -->line#*=} addConfig "${key}" "${value}" done echo "=========================================================================" echo " Complete initialization parameters, total-count:$count , failure-count:$failCount " echo "=========================================================================" if [[ ${<!-- -->failCount} -eq 0 ]]; then echo " Init nacos config finished, please start seata-server. " else echo " init nacos config fail. " fi |
2.运行脚本,运行脚本命令:sh nacos-config.sh [-h host] [-p port] [-g group] [-t tenant] [-u username] [-w password];
-h nacos地址
-p nacos端口,默认 8848
-g nacos配置组
-t naocos的命名空间id
-u -p 登录nacos的账号、密码
nacos-config.sh和config.txt文件位置需如下放置到同一目录:
运行命令如下:
成功后会在Nacos配置中心看到相关配置。如下说明执行成功。
- 准备服务端配置registry.conf
注册和配置中心均选择nacos,然后填写相关信息。如下是我的配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | registry {<!-- --> type = "nacos" nacos {<!-- --> serverAddr = "111.231.111.150:8848" application = "seata-server" group = "SEATA_GROUP" namespace = "0f342584-17a7-4247-8496-77817c889e2e" cluster = "default" } } config {<!-- --> type = "nacos" nacos {<!-- --> serverAddr = "111.231.111.150:8848" namespace = "0f342584-17a7-4247-8496-77817c889e2e" group = "SEATA_GROUP" } } |
- Docker安装seata服务端。
-e SEATA_IP 指定当前机器的公网ip。
-e SEATA_CONFIG_NAME 指定配置文件位置
1 2 3 4 5 6 | docker run --name seata-server \ -p 8091:8091 -e SEATA_IP=111.231.111.150 \ -e SEATA_CONFIG_NAME=file:/root/seata-config/registry \ --restart=always -d \ -v /usr/gourd/docker/seata/config:/root/seata-config \ seataio/seata-server:1.3.0 |
执行如下:
docker logs 查看容器日志,如下说明seata服务启动成功。
注:如果你服务启动报如下错误,需要将nacos中相应store.db.driver-class-name调整为store.db.driverClassName,然后rm掉镜像后,重启启动。
Caused by: io.seata.common.exception.StoreException: the {store.db.driverClassName} can’t be empty
- 客户端项目配置调整,删除resources目录下registry.conf、file.conf文件,在yml中增加如下配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # seata 分布式事务 seata: enabled: true application-id: ${<!-- -->spring.application.name} enable-auto-data-source-proxy: false tx-service-group: admin-tx_group service: vgroup-mapping: admin-tx_group: default #key与上面的tx-service-group的值对应 registry: type: nacos nacos: server-addr: ${<!-- -->spring.cloud.nacos.config.server-addr} namespace: 0f342584-17a7-4247-8496-77817c889e2e group: SEATA_GROUP cluster: default |
到此所有准备就完成了,直接启动项目测试。我测试下来是ok的。
结语
以上就是升级seata遇到的种种坑,及解决方法。如果你还有其他的问题欢迎留言交流。
seata官方文档:http://seata.io/zh-cn/docs/ops/upgrade.html
代码摘自本人的开源项目cloud-plus:https://blog.csdn.net/HXNLYW/article/details/104635673