0


Spring Boot 升级3.x 指南

Spring Boot 升级3.x 指南

1. 升级思路

先创建一个parent项目,打包类型为pom,继承自spring boot的parent项目

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.x</version>
</parent>

然后把版本集中放在这个pom里面,示例如下

<properties><!-- 建议添加全局变量 java.version,maven.compiler.source, maven.compiler.target--><java.version>17</java.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><spring-cloud-dependencies.version>2022.0.4</spring-cloud-dependencies.version><spring-cloud-starter-netflix.version>2.2.10.RELEASE</spring-cloud-starter-netflix.version></properties>

然后添加

dependencyManagement

节点,示例如下:

<dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud-dependencies.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId><version>${spring-cloud-starter-netflix.version}</version><exclusions><exclusion><artifactId>jsr311-api</artifactId><groupId>javax.ws.rs</groupId></exclusion><exclusion><artifactId>jackson-annotations</artifactId><groupId>com.fasterxml.jackson.core</groupId></exclusion><exclusion><artifactId>jackson-core</artifactId><groupId>com.fasterxml.jackson.core</groupId></exclusion><exclusion><artifactId>jackson-databind</artifactId><groupId>com.fasterxml.jackson.core</groupId></exclusion><exclusion><artifactId>guava</artifactId><groupId>com.google.guava</groupId></exclusion></exclusions></dependency><dependencies></dependencyManagement>

其它服务都继承这个pom文件,这样各个组件的版本就能统一起来了,将来如果某个组件要升级,直接升级这个项目的版本,其它的重新打包发布即可。

注意:

  1. 动手前一定要调研项目中使用的组件,某些组件是没法升级的。比如ElasticSearch,驱动版本和ElasticSearch server版本要一致,升级了就会报错。其它常见组件的有Nacos,Kafka,Mysql,RocketMQ,需要调研是否兼容低版本。
  2. 如果之前使用了Zuul 1.x作为Gateway,Zuul 2.x不开源并且难以升级,建议升级到Spring Cloud Gateway
  3. 如果使用了Zuul1.x的作为Proxy嵌入服务中,有两个思路,一个是使用Filter+HttpClient手动写转发代码,第二个思路是调研调用接口,使用Feign做转发
  4. Spring Boot 3.x 需要JDK17,建议使用OpenJDK17,Oracle的JDK17可能存在授权问题

2. 遇到的问题

  1. Zuul1.x 升级Spring Cloud Gateway,可以参考 (Zuul迁移至Spring Cloud Gateway踩坑记录)[https://blog.csdn.net/codeblf2/article/details/128093298] ,此记录中服务使用的是k8s部署,转发直接配置uri,如果使用的是Nacos,网络上博客比较多,这里不再赘述。
  2. 如果是Spring Boot 1.x升级上来的,可能要注意循环依赖,添加以下可以解决:spring:main:allow-circular-references:true
  3. Spring Boot 3.x 支持优雅退出,添加以下配置开启# 打开优雅退出server:shutdown: graceful# 多长时间后强制杀掉进程spring:lifecycle:timeout-per-shutdown-phase: 30s
  4. Beancopier可能没法用了,可以使用BeanUtil.copyProperties替换
  5. JDK8升级到JDK17,javax包变成了jakarta,需要替换所有的javax.annotation和javax.validation等,但javax.mail没有变,当jakarta.xxx不存在时,还是使用javax.xxx即可
  6. 如果引入外部配置文件,使用spring.cloud.bootstrap.additional-location=/data/config/bootstrap.yml,/data/config/bootstrap2.yml即可
  7. 如果依赖的一些jar中依赖一些类但由于升级,依赖类已经不存在了,典型的就是WebMvcConfigurerAdapter.class,之前是继承WebMvcConfigurerAdapter,Spring Boot 3.x 已经改成了实现接口WebMvcConfigurer,可能会出现FileNotFoundException,此时可能难以定位是哪个jar,参考SpringBoot版本升级引起的FileNotFoundException——WebMvcConfigurerAdapter.class
  8. Spring Cloud Gateway 配置文件参考(可能遇到的问题已经写在了注释中):spring:cloud:gateway:# 默认过滤器default-filters:# 将path中第一个/xxx去掉 比如请求是 https://www.xxx.com/a/b/c?d=1# 经过这个过滤器之后就是 https://www.xxx.com/b/c?d=1- StripPrefix=1 # 下面这两个过滤器是gateway和后面的服务都配置了跨域头,防止返同样的回头有多个导致跨域失败# 典型的 access-control-allow-credentials: true,true 返回到前端导致跨域失败- DedupeResponseHeader=access-control-allow-credentials,RETAIN_UNIQUE - DedupeResponseHeader=access-control-allow-origin,RETAIN_UNIQUE routes:# 服务名-id: user # 转发到的url 下面的示例是k8s内部转发# 如果使用服务名转发 开头应该是lb:xxx# 这个端口后不要加任何东西 因为转发的时候会忽略掉# 比如 http://service-user.inner:8080/aaa最后拼接出来是http://service-user.inner:8080,/aaa就忽略了uri: http://service-user.inner:8080predicates:# 匹配的请求url中的path 下面这个会匹配到 http://www.xxx.com/gateway/user/login?userName=AAA- Path=/gateway/user/**filters:# StripPrefix:去除原始请求路径中的前1级路径# 会把 http://www.xxx.com/gateway/service1/login中的service1去掉- StripPrefix=1 # 在转发后的url添加的前缀 经过这个filter 转发url就变成了 http://service-user.inner:8080/service-user- PrefixPath=/service-user # 这里讲一下全流程# 以请求为 http://www.xxx.com/gateway/user/login?userName=AAA为例 这个url是要登录,登录服务名为service-user# 断言规则 spring.cloud.routes > predicates > Path=/gateway/user/** 能匹配到url http://www.xxx.com/gateway/user/login?userName=AAA# 第一步是默认过滤器 经过 spring.cloud.gateway.default-filters > StripPrefix=1 这个配置后就变成了 http://www.xxx.com/user/login?userName=AAA# 第二步是routers过滤器 spring.cloud.routes下的id=user的 filters > StripPrefix=1会将 http://www.xxx.com/user/login?userName=AAA的/user去掉,变成了 http://www.xxx.com/login?userName=AAA 变成# 第三步是routers过滤器 spring.cloud.routes下的id=user的 filters > PrefixPath=/service-user 会将 http://www.xxx.com/login?userName=AAA 变成 http://service-user.inner:8080/service-user服务/login?userName=AAA# 经过上面的处理后,最终会转发到 service-user服务# response中的header如果有跨域header 会经过 spring.cloud.gateway.default-filters > DedupeResponseHeader过滤器将重复的header去掉
标签: spring boot 后端 java

本文转载自: https://blog.csdn.net/u013014691/article/details/134585457
版权归原作者 BLF2 所有, 如有侵权,请联系我们删除。

“Spring Boot 升级3.x 指南”的评论:

还没有评论