SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结

开始

Spring Boot 最新版本已经到了3.1.x版本,线上目前用的2.1版本官方已经停止支持,目前打算先做一定的技术预研,在不升级JDK的前提下,削减升级坡度,预先升级到2.7.10版本GA版本。

SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第1张图片

SpringBoot官方版本支持说明:(写这边文章时从2.7.9变成了2.7.10)

官方文档:https://spring.io/projects/spring-boot#support
SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第2张图片

官方Github Release: https://github.com/spring-projects/spring-boot/releases/tag/v2.7.10

spring cloud 版本
SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第3张图片
里面升级jar包,修复logger包的漏洞,fastjson漏洞也会随着这次升级一道修复
image.png

废话不多说,直接开始:


依赖处理与功能升级

SpringBoot主包升级

我们将springboot主包从2.1.9.RELEASE 修改为2.7.10.

    
        org.springframework.boot
        spring-boot-starter-parent
        2.7.10
        
    

SpringCloud组件升级

SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第4张图片
目前Spring Cloud Alibaba 与cloud 基于spring boot 2.7.10的兼容版本


    org.springframework.cloud
    spring-cloud-dependencies
    2021.0.5



    com.alibaba.cloud
    spring-cloud-alibaba-dependencies
    2021.0.5.0

这时候发现SpringCloud被逼在2020版本移除了对Netflix OSS大部分组件的支持

Spring Cloud官方尤其着重指出ribbon、hystrix 和 zuul 从Spring Cloud 2020.0正式版发布后将不再被Spring Cloud支持。在目前最新的Spring Cloud 2020.0中仅仅剩下了Eureka。但是留给Eureka的时间也不多了。

其中ribbon 替换为SpringCloud LoadBalance 组件,收录在SpringCloud Commons 里面
文档如下:

参考博客:https://docs.spring.io/spring-cloud-commons/docs/current/refe...

使用上和ribbon没有什么不同,使用 @LoadBalanced 手动声明 RestTemplate Bean

    @ConditionalOnMissingBean(RestTemplate.class)
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(@Qualifier("myMappingJackson2HttpMessageConverter") MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter) {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getInterceptors().add(new CoreHttpRequestInterceptor());
        //RestTemplate解决Date数据类型反序列化的问题,使用自定义的MappingJackson2HttpMessageConverter覆盖
        restTemplate.getMessageConverters().add(5, mappingJackson2HttpMessageConverter);
        return restTemplate;
    }

hystrix可以考虑使用Spring Cloud Alibaba的Sentinel做熔断和流控

下面开始做hystirx到Sentinel迁移:
首先是pom替换

        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-sentinel
        




        

项目里面继续使用openfeign做rpc调用,将application.properties里面feign的熔断实现配置修改为sentinel实现。

# 去掉
# feign.hystrix.enabled: true
# 改为如下即可
feign.sentinel.enabled: true

SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第5张图片

这里故意将order服务配置错,查看rpc调用信息,可以看到使用了loadbalance 和sentinel

FeignClient基于sentinel对fallbackFactory统一降级的优化处理

由于熔断需要,业务降级时,需要手写fallback业务,但是并不是所有的RPC都需要写降级代码,所以才有了定义统一业务Reuslt返回fallback降级信息,代替框架的没有配置就throw Exception的逻辑。
之前Netflix时,是feign结合hystrix做,现在升级后,需要使用sentinel逻辑再改一遍。

参考博客:https://blog.csdn.net/qq_40592377/article/details/105142856

cloud的 openfeign和alibaba 的sentinel包里面移除了如下包依赖,彻底和hystrix告别了


      io.github.openfeign
      feign-hystrix
      10.4.0
      compile
    

SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第6张图片

这里是重新修改后的代码
修改处1 使用反射构造SentinelInvocationHandler是因为他不提供public构造方法
修改处2 使用了我自己定义的统一Result业务错误Result的FeignFallback。

Feign对于上游参数的透传 TODO

之前是自定义HystrixConcurrencyStrategy实现,在微服务之间RPC调用时,实现请求的业务header值,跨线程池透递
目前改用sentinel之后,还没有研究透彻,有待后续优化。

Bean循环引用的问题

重启系统,发现报错如下,因为SpringBoot 2.6开始默认禁止循环引用,这时候改业务就有麻烦,先修改为强制同意。

> 
Description:

  The dependencies of some of the beans in the application context form a cycle:
  略
  ↓
  sqlSessionFactory defined in class path resource [com/suike/config/database/MyBatisConfig.class]
  ┌─────┐
  | dataSource defined in class path resource [com/suike/config/database/MyBatisConfig.class]
  ↑ ↓
  | dataSourceDev defined in class path resource [com/suike/config/database/dataSource/DruidDBConfigDev.class]
  ↑ ↓
  | dataSourceInitializer
  └─────┘

在项目Starter文件中修改 setAllowCircularReferences(Boolean.TRUE);

    public static void main(String[] args) {
        log.info(">>>>>>>> steamcdk-activitys 启动开始 >>>>>>>>>");
        SpringApplication application = new SpringApplication(ActivityStarter.class);
        //暂时先允许循环引用,后面再清理业务。做规范
        application.setAllowCircularReferences(Boolean.TRUE);
        application.run(args);
        log.info(">>>>>>>> steamcdk-activitys 启动完成 >>>>>>>>>");
    }
参考:https://blog.csdn.net/Dug_Zhang/article/details/122225331

依赖组件Nacos Server版本升级

重启项目,再次报错:

ErrCode:-401, ErrMsg:Client not connected,current status:STARTING

询问度娘得知,Alibaba2.2.7中nacos client 依赖的server 必须也是2.x 以上,而我这边项目之前用的是nacos-servcer-1.4.1
没辙,去nacos官方查1.x升级2.x升级文档:

nacos git地址: https://github.com/alibaba/nacos/releases
nacos2.0升级文档: https://nacos.io/zh-cn/docs/2.0.0-upgrading.html

覆盖文件,然后修改下配置就好了,双写先开着,老系统还在用。

ErrCode:-400, ErrMsg:Could not initialize class com.alibaba.nacos.common.remote.client.grpc.GrpcSdkClient

nacos 升级成2.2.0 ,以下是alibaba 官方版本匹配

SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第7张图片

Springfox 升级为Springdoc

重启一下,T T,继续!
image.png

网上说如果要继续用Springfox,只需要加一段配置

spring.mvc.pathmatch.matching-strategy=ant_path_matcher

但是后面肯定还会有兼容性问题,再次求助得知:Spring基于Swagger3自己做了一套基于openapi3规范的文档项目,叫springDoc.

参考:https://zhuanlan.zhihu.com/p/439255980

忙活了半天,还是决定替换成SpringDoc,首先是springfox 已经很久没有更新了
其实,改版后发现Springdoc 确实做的比springfox更适合spring体系。

文档地址:https://springdoc.org/#demos

替换注解,重写OpenAPI的配置文件,参考文档,成功平滑替换
SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第8张图片

Redis线程池改动

特别注意,spring date redis 依赖的commons-pool2 2.9.0会报错,需要另外声明为最新


    org.apache.commons
    commons-pool2
    2.11.1

在Springboot 2x以后,底层访问redis已经不再是jedis了,而是lettuce
SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第9张图片
这边配置修改为使用lettuce链接池

MYSQL连接器 版本升级

MySQL的链接驱动, 从 8.0.31 开始,从原来的 mysql:mysql-connector-java 改为 com.mysql:mysql-connector-j

网关中,关于exclude Url匹配规则升级

> org.springframework.web.util.pattern.PatternParseException: No more pattern data allowed after {*...} or ** pattern element

错误直观展示是路径统配问题,可是之前没有问题啊,后来经过一通查找发现是spring升级到5.3之后路径统配发生了变化,官方给出的解释是“In Spring MVC, the path was previously analyzed by AntPathMatcher, but it was changed to use PathPatternParser introduced in WebFlux from Spring 5.3.0.”。

2、具体解决是把/**/*.html 改为 /*/*.html,项目中可能涉及多个文件,都要改:
SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第10张图片

OK,修改完重启。不出所料再次遇到问题

网关使用Loadbalancer代替Ribbon实现负载均衡

访问服务网关进行路由时,找不到服务
SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第11张图片
gateway配置一切正常,鉴权也没有问题,nacos也正常注册,但是路由的时候就是找不到服务

解决方法:在pom.xml文件中添加如下依赖:




    org.springframework.cloud
    spring-cloud-starter-loadbalancer

原因:由于springcloud2020弃用了Ribbon,因此Alibaba在2021版本nacos中删除了Ribbon的jar包,因此无法通过lb路由到指定微服务,出现了503情况。
所以只需要引入springcloud loadbalancer包即可

fastJson严重漏洞,升级为1.2.83版本

image.png

项目启动时,加入如下代码

    /*
 * Fastjson存在远程代码执行漏洞 升级到最新版本1.2.83  打开autotype功能
 * @see https://github.com/alibaba/fastjson/wiki/enable_autotype
 */
ParserConfig.getGlobalInstance().addDeny("com.rush.gameup");

非必须升级

Mybatis-plus从3.2升级到3.5

mybatis-plus可以说是用lambda语法写sql,体感非常丝滑。
在3.5中,主要改动是代码生成器的api升级,变得更强大了。
SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第12张图片
这里我通过mybatis-generator生成时指定我抽象出的一套扩展父类,可以加快不少开发速度
更进阶的话,手挫 100% 契合自己业务的vm、ftl模板,想象空间很大。

也可以体验下@EnumValue,@TableLogic的“花活”。

文档地址 https://baomidou.com/pages/24112f/

Gateway使用knife4j聚合swagger文档并优化ui

升级后的spring doc的UI美观了一些

SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第13张图片SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第14张图片

但是现在有一个国人开源的更强大的UI插件:knife4j

界面效果如下图,下拉框里会列出nacos里面注册的所有服务,knife4j会自动装配进来,选中即可查看文档
SpringBoot2.2升级到2.7.9遇到的问题及解决方案总结_第15张图片


    com.github.xiaoymin
    knife4j-gateway-spring-boot-starter
    4.1.0

最新4.1版本Gateway只需要如下的简单配置,就可以自动注册和聚合所有微服务的swagger文档,比我之前手动写个聚合页使用体验要强上许多。

knife4j:
  gateway:
    # 指定服务发现的模式聚合微服务文档,并且是默认`default`分组
    strategy: discover
    discover:
      # 指定版本号(Swagger2|OpenAPI3)
      version: openapi3
      enabled: true
    enabled: true
参考文档:https://doc.xiaominfo.com/docs/changelog/x/4.1

你可能感兴趣的:(springboot微服务)