4

我服了!SpringBoot升级后这服务我一个星期都没跑起来!(上) - 艾小仙

 1 year ago
source link: https://www.cnblogs.com/ilovejaney/p/16870863.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

最近由于各方面的原因在准备升级 Spring Cloud 和 Spring Boot,经过一系列前置的调研和分析,决定把Spring Boot 相关版本从 2.1.6 升级到 2.7.5,Spring Cloud 相关版本从 Greenwich.SR1 升级为 2021.0.4。

升级包含基础的业务服务代码的升级改造适配,还有就是中间件一堆代码的改造,上周经历了一周的修改,用来测试的服务仍然还没有跑起来,所以这篇文章我会记录下来这升级过程中的一些问题,由于革命仍未成功,所以这是上篇。

1. hibernate-validator包下的类报错

在 Spring Boot 2.3版本之后,spring-boot-starter-web 中没有依赖 hibernate-validator。

解决方案:使用新的依赖。

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2. ApplicationEnvironmentPreparedEvent类改变

Spring Boot 2.4版本之后,ApplicationEnvironmentPreparedEvent 构造函数新增了ConfigurableBootstrapContext,业务代码还好,应该都用不上这个类,中间件代码使用到的地方都需要修改。

解决方案:修改代码。

public ApplicationEnvironmentPreparedEvent(ConfigurableBootstrapContext bootstrapContext,
			SpringApplication application, String[] args, ConfigurableEnvironment environment) {
		super(application, args);
		this.bootstrapContext = bootstrapContext;
		this.environment = environment;
	}
008vxvgGgy1h7wov31s9rj31dj0u07c9.jpg

3. junit依赖升级

升级后的junit版本默认是junit5(我没有去确认是哪个版本发生了变化),升级之后包名发生了改变,所有的测试用例都需要修改。

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

另外发现Assert类不存在了,可以改用Assertions

Assertions.assertNotNull(result);

解决方案:修改代码!

4. Spring Cloud兼容问题

由于测试过程中先升级的 Spring Boot,发现 Spring Cloud 使用到的低版本代码不兼容,升级到文章开头说的版本之后问题解决。

比如下面的 spring-cloud-context 启动时候报错。

008vxvgGgy1h7wov18cm8j320b0u0k1e.jpg

5. SpringApplicationRunListener类改变

和第二个问题比较类似,SpringApplicationRunListener 中这两个方法新增了 ConfigurableBootstrapContext,对应实现类都需要修改,这个应该无论在业务还是中间件代码中都应该有大量的使用。

解决方案:修改代码!

default void starting(ConfigurableBootstrapContext bootstrapContext) {}
default void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,ConfigurableEnvironment environment) {}

6. ServerProperties变更

spring-boot-autoconfigure 包下 ServerProperties 中的内部类 Tomcat 属性变更,获取最大线程数方法发生改变。

原写法:serverProperties.getTomcat().getMaxThreads()

解决方案:serverProperties.getTomcat().getThreads().getMax()

7. spring-cloud-openfeign中移除ribbon和hystrix依赖

Commit地址:https://github.com/spring-cloud/spring-cloud-openfeign/commit/8a08e1ec4b4f0d40193a4ea9c03afdeffe3110a6

这个提交把 spring-cloud-openfeign 里面关于 ribbon 和 hystrix 的依赖相关代码全部删除了,这个 commit 我找了一遍 issue 和 PR,都没有发现相关说明,大佬直接删的,具体原因不清楚为什么直接全删干净了。

比如我的启动报错:

Caused by: java.lang.ClassNotFoundException: org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient

解决方案:手动引入新的依赖。

 <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
   <version>2.2.10.RELEASE</version>
 </dependency>

8. bootstrap.properties/yml 配置文件不生效

根据 Spring Cloud 配置方式,发现很多业务的本地配置配置在 bootstrap.properties中,新版本默认会不生效。

老版本中 spring.cloud.bootstrap.enabled 默认为 true。

008vxvgGgy1h7wov41gwlj31bt0u0wmw.jpg

新版本改过之后默认是false了,导致一堆配置不生效。

008vxvgGgy1h7wov3ktutj322k0jojx6.jpg

008vxvgGgy1h7wov21frvj31ne06iwfu.jpg

解决方案:手动设置spring.cloud.bootstrap.enabled=true

9. spring-cloud-netflix-eureka-client中移除ribbon和hystrix依赖

和第七个问题差不多,spring-cloud-netflix-eureka-client 移除了 ribbon和hystrix依赖,所以客户端默认不会有ribbon这些东西了。

解决方案:手动引入新的依赖。

 <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
   <version>2.2.10.RELEASE</version>
 </dependency>

10. spring-cloud-starter-alibaba-sentinel版本不兼容

spring-cloud-starter-alibaba-sentinel 使用的是 2.1.3.RELEASE ,和新版本存在兼容性问题,导致无法启动,存在循环依赖问题。

报错信息:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.alibaba.cloud.sentinel.SentinelWebAutoConfiguration': Unsatisfied dependency expressed through field 'sentinelWebInterceptorOptional'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'com.alibaba.cloud.sentinel.SentinelWebAutoConfiguration': Requested bean is currently in creation: Is there an unresolvable circular reference?

解决方案:升级为当前 Spring Cloud 一样的版本。

 <dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
   <version>2021.0.4.0</version>
 </dependency>

11. commons-pool2兼容性报错

spring-boot-autoconfigure 2.7.5版本中 JedisConnectionConfiguration 报错,原因在于我们有的业务代码依赖中自己指定了 commons-pool2的版本。

008vxvgGgy1h7wtlem9gqj32960u0dql.jpg
Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:
    org.springframework.boot.autoconfigure.data.redis.JedisConnectionConfiguration.jedisPoolConfig(JedisConnectionConfiguration.java:114)

The following method did not exist:

    redis.clients.jedis.JedisPoolConfig.setMaxWait(Ljava/time/Duration;)V

Action:

Correct the classpath of your application so that it contains compatible versions of the classes org.springframework.boot.autoconfigure.data.redis.JedisConnectionConfiguration and redis.clients.jedis.JedisPoolConfig

Git Issue :https://github.com/spring-projects/spring-boot/issues/27642

看这个时间很早就修正了,commons-pool2 在2.8.1版本后丢失了一些方法。

解决方案:自己不要指定该包版本默认会使用 spring boot 的最新依赖,或者手动指定最新版本2.11.1。

12. 循环依赖报错

spring-boot 2.6版本之后禁止循环依赖,有的话启动会报错,报错信息和第十个问题是一样的,不同的是业务代码的报错而已。

解决方案:手动解决代码循环依赖问题或者设置属性 spring.main.allow-circular-references=true

13. spring-rabbit 版本兼容

升级之后,由于中间件封装了 rabbit 的一些功能,去掉了 spring-rabbit的自动装配,导致基本上整个中间件包不可用,大量方法不兼容。

解决方案:全部用2.7.5版本的代码覆盖自动装配的逻辑。

008vxvgGgy1h7wov0ai6oj32aa0l2qa3.jpg

看起来这些问题都只是一两句话的功夫,但是实际上花了大量的时间在排查、找解决方案,还有把所有现在依赖的包版本重新筛查,修改包版本、重新打包测试版本,中间非人体验实在不是一两句话能说清楚的,我觉得,做业务开发其实也挺好的。

目前革命还只是进行了一小步,还有更多的问题需要去解决,不过这个星期必须全部解决!!!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK