springboot集成Seata升级避坑之undo序列化方式选择

场景描述

因近段时间nacos接连爆出安全问题及最新发布的版本2.0.0相比较1.X来说,性能和各方面都有了较大提升,故,就对目前项目的基础微服务版本做了一次升级。分为2部分操作,其一就是将nacos的版本从1.3.2提升到2.0.1版本。其二就是对项目中使用的依赖进行对等版本的升级。整个过程来说比较顺利,项目中各组件升级后各核心功能点验证都很正常,但是在验证seata功能时,出现异常,这就是题目所说的升级中的坑。问题的原因及解决方式请继续往下看。

升级nacos

nacos的版本升级较为正常,1.3.2 根2.0.1版本从部署的操作来讲区别不大。首先对应的表结构没有改变,唯一的区别是nacos2.0.1版本将config_info、config_info_beta、config_info_tag、his_config_info 表中的 src_ip 的字段长度从20增加到50,仅此一个不同。其次,部署方式方式来讲没有区别,就是解压,修改配置,启动即可。

项目jar包升级

可能有些人会有疑问,升级nacos的版本,怎么会导致seata的问题?按照情况,升级nacos,对应修改项目中nacos的版本即可,这其实不会导致seata出问题。这其实是跟项目中的包引用有关系,升级前,项目中基础包及版本如下:

<spring-cloud-alibaba-dependencies.version>2.2.3.RELEASE</spring-cloud-alibaba-dependencies.version>
<spring-boot-dependencies.version>2.2.10.RELEASE</spring-boot-dependencies.version>
<spring-cloud-dependencies.version>Hoxton.SR8</spring-cloud-dependencies.version>

如上所示,并不是采用单个引入的方式,而是采用引入集体依赖的方式,也就是为什么升级nacos会印象到seata的问题。

根据一般的常识,项目中开发使用的组件要和对应服务器上组件的版本一致。所以,当升级了nacos之后,第一步,我们就需要升级
spring-cloud-alibaba-dependencies.version 版本。

首先来看看下面这个版本(2.2.3.RELEASE)下各组件的版本:

springboot集成Seata升级避坑之undo序列化方式选择

对应nacos的版本为1.3.3,这也就是这里要升级
spring-cloud-alibaba-dependencies.version 版本的原因。而其具体升级到多少版本,需要参考阿里给出的版本说明:

springboot集成Seata升级避坑之undo序列化方式选择

通过图表可知对应关系,我们这里选择的版本是:2.2.5.RELEASE。你可能关注到nacos对应的版本为1.4.1,不过,没有关系,经过确认,目前是可以支持2.0.1版本的。

那么,其他的依赖改:
spring-boot-dependencies.version和spring-cloud-dependencies.version如何选择,依然是通过阿里给出的版本说明:

springboot集成Seata升级避坑之undo序列化方式选择

这里可以根据这个表里面的版本,因为标注是推荐使用,也可以根据个人情况选择折中的版本,而我则是使用的折中版本。升级选择的对应版本如下:

<spring-cloud-alibaba-dependencies.version>2.2.5.RELEASE</spring-cloud-alibaba-dependencies.version>
<spring-boot-dependencies.version>2.3.11.RELEASE</spring-boot-dependencies.version>
<spring-cloud-dependencies.version>Hoxton.SR9</spring-cloud-dependencies.version>

升级版本后的问题及解决方法

相关jar升级后进行验证,只有seata验证时出现问题,对应报错信息如下:

springboot集成Seata升级避坑之undo序列化方式选择

部分报错信息如:

13:27:20.526 [rpcDispatch_RMROLE_1_10_16] INFO  i.s.r.AbstractRMHandler - [doBranchRollback,123] - Branch Rollbacking: 192.168.35.53:8091:140447923132436480 140445676436729857 jdbc:mysql://192.168.35.53:3306/oauth-center
13:27:20.627 [rpcDispatch_RMROLE_1_10_16] ERROR i.s.r.d.u.p.JacksonUndoLogParser - [decode,143] - json decode exception, Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (byte[])"{"@class":"io.seata.rm.datasource.undo.BranchUndoLog","xid":"192.168.35.53:8091:140447923132436480","branchId":140445676436729857,"sqlUndoLogs":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.undo.SQLUndoLog","sqlType":"INSERT","tableName":"oauth_client_details","beforeImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords$EmptyTableRecords","tableName":"oauth_client_details","rows":["java.util.ArrayList",[]]},"afterImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRec"[truncated 8910 bytes]; line: 1, column: 2460] (through reference chain:

通过错误信息可以很快就可以定位问题,是jackson序列化属性的问题,可是,我们升级过程并没有改动逻辑代码,仅仅是升级版本就出现了问题,很明显,导致问题的原因是对应版本的问题。

那么,问题产生的原因是什么?该如何解决问题?

问题产生的原因是我们可以再SEATA官网中FAQ中找到原因:

springboot集成Seata升级避坑之undo序列化方式选择

由描述可知,使用jackson的方式后续也会出现问题,完美解决方案就是修改

client.undo.logSerialization属性为kryo。

目前seata的配置中心未nacos,所以,增加这个配置,需要将对应属性配置到nacos中即可。需要特别注意,对应namespace和group需要对应上。

配置如下:

springboot集成Seata升级避坑之undo序列化方式选择

需要特别注意:配置完需首先清空seata的表(bransh_table,global_table,lock_table)内容然后重启seata!

如果不清空seata表,当项目启动的时候,会不断的进行重试事物导致系统无法正常启动。

重启seata则是为了是配置配置生效。根据seata机制,仅对部分属性进行了监听,而此序列化属性未进行监听,只能重启时进行加载。

据seata项目组人员反馈,此问题会在seata1.5版本中解决。

验证

重启seata后,系统可以正常启动,开始进行功能验证。

这是系统依然报错:

springboot集成Seata升级避坑之undo序列化方式选择

引入依赖:

<dependency>
    <groupId>com.esotericsoftware</groupId>
    <artifactId>kryo</artifactId>
    <version>4.0.2</version>
</dependency>

项目重启后继续验证,依然报错:

springboot集成Seata升级避坑之undo序列化方式选择

继续引入依赖:

<dependency>
      <groupId>de.javakaffee</groupId>
      <artifactId>kryo-serializers</artifactId>
      <version>0.44</version>
  </dependency>

重启后验证功能,功能正常。

以上为全部内容。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot集成Seata,需要进行以下步骤: 1.添加Seata的依赖。在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> <version>${seata.version}</version> </dependency> ``` 2.配置Seata。在application.properties或application.yml文件中添加以下配置: ```yaml spring: application: name: ${spring.application.name} cloud: alibaba: seata: tx-service-group: ${spring.application.name}-fescar-service-group seata: enabled: true application-id: ${spring.application.name} tx-service-group: ${spring.application.name}-fescar-service-group config: type: nacos nacos: serverAddr: ${nacos.server-addr:localhost:8848} namespace: ${nacos.namespace:public} registry: type: nacos nacos: serverAddr: ${nacos.server-addr:localhost:8848} namespace: ${nacos.namespace:public} service: vgroupMapping: ${spring.application.name}-fescar-service-group: default groupMapping: ${spring.application.name}-fescar-service-group: "default" transport: type: TCP tcp: selector: ${seata.selector:org.apache.seata.core.rpc.netty.NettyClientConfig} clientWorkerThreads: ${seata.client.worker.thread.size:NettyRuntime.availableProcessors()} bossThreadSize: ${seata.boss.thread.size:1} shutdownWait: ${seata.shutdown.wait:3} maxConnection: ${seata.max.commit.retry.timeout:1} connectionWaitTimeout: ${seata.max.commit.retry.timeout:5000} idleTimeout: ${seata.max.commit.retry.timeout:300000} heartbeatTimeout: ${seata.heartbeat.timeout:1000} ``` 3.配置数据源。在application.properties或application.yml文件中添加以下配置: ```yaml spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/seata?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root ``` 4.配置MyBatis。在MyBatis的配置文件中添加以下配置: ```xml <configuration> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <typeAliases> <package name="com.xxx.xxx.entity"/> </typeAliases> <plugins> <plugin interceptor="io.seata.rm.datasource.mybatis.SeataInterceptor"/> </plugins> </configuration> ``` 5.启动Seata Server。在Seata Server的bin目录下执行以下命令: ```shell sh seata-server.sh -p 8091 -m file ``` 6.启动应用程序。在Spring Boot应用程序的启动类上添加@SeataApplication注解。 ```java @SpringBootApplication @SeataApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值