场景描述
因近段时间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)下各组件的版本:
对应nacos的版本为1.3.3,这也就是这里要升级
spring-cloud-alibaba-dependencies.version 版本的原因。而其具体升级到多少版本,需要参考阿里给出的版本说明:
通过图表可知对应关系,我们这里选择的版本是:2.2.5.RELEASE。你可能关注到nacos对应的版本为1.4.1,不过,没有关系,经过确认,目前是可以支持2.0.1版本的。
那么,其他的依赖改:
spring-boot-dependencies.version和spring-cloud-dependencies.version如何选择,依然是通过阿里给出的版本说明:
这里可以根据这个表里面的版本,因为标注是推荐使用,也可以根据个人情况选择折中的版本,而我则是使用的折中版本。升级选择的对应版本如下:
<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验证时出现问题,对应报错信息如下:
部分报错信息如:
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中找到原因:
由描述可知,使用jackson的方式后续也会出现问题,完美解决方案就是修改
client.undo.logSerialization属性为kryo。
目前seata的配置中心未nacos,所以,增加这个配置,需要将对应属性配置到nacos中即可。需要特别注意,对应namespace和group需要对应上。
配置如下:
需要特别注意:配置完需首先清空seata的表(bransh_table,global_table,lock_table)内容然后重启seata!
如果不清空seata表,当项目启动的时候,会不断的进行重试事物导致系统无法正常启动。
重启seata则是为了是配置配置生效。根据seata机制,仅对部分属性进行了监听,而此序列化属性未进行监听,只能重启时进行加载。
据seata项目组人员反馈,此问题会在seata1.5版本中解决。
验证
重启seata后,系统可以正常启动,开始进行功能验证。
这是系统依然报错:
引入依赖:
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>4.0.2</version>
</dependency>
项目重启后继续验证,依然报错:
继续引入依赖:
<dependency>
<groupId>de.javakaffee</groupId>
<artifactId>kryo-serializers</artifactId>
<version>0.44</version>
</dependency>
重启后验证功能,功能正常。
以上为全部内容。