美文网首页java
SpringBoot1.x升级到2.x实践

SpringBoot1.x升级到2.x实践

作者: terry蒋 | 来源:发表于2020-03-08 17:57 被阅读0次

    一、简述

    1.文章由来

    公司内部一直使用1.5.9.RELEASE版本的springboot,今年计划升级到2.x版本,本人在其中一个项目中升到到2.x并在生产上使用约4个月后整理了一些经验,在研发部进行分享。原稿改编后整理在博客中。

    2.升级原因

    1.直接原因:log4j存在危险的安全漏洞,需要升级log4j版本。springboot1.5.9.RELEASE版本默认用的是2.7版本的log4j,替换为2.8.2之后的版本或者升级springboot版本可以解决问题。

    2.版本过旧,有些已经闭源,或存在历史漏洞。1.5.9.RELEASE是2017年11月份发行,截止到现在,已经验证出许多漏洞,并通过版本升级修复了漏洞。

    公司的devops平台的流水线构建时通过HUB扫描发现,历史版本有许多中高级的安全漏洞,必须升级修复。

    3.新版本有很多有用的特性。

    比如:2.x版本默认使用当前java中性能最好的HikariCP做数据库连接池。https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Configuration-Changelog

    3.同步升级spring-cloud

    springboot升级,依赖的spring也会随之升级。此外,springcloud版本需要和springboot兼容,在springboot版本升级比较大的情况下,也可能需要升级。

    参考:springboot-springcloud版本对应表:https://start.spring.io/actuator/info

    springboot-springcloud版本对应表.png

    推荐项目使用的版本:

    springboot springcloud spring
    升级前 1.5.9.RELEASE Edgware.SR1 4.3.13.RELEASE
    升级后 2.1.5.RELEASE Greenwich.SR3 5.1.7.RELEASE

    二、解决版本变化遇到的问题

    新旧版本有许多设计上的变化,如果不一一检查,并做相应改动,将导致许多程序问题!
    每个项目使用的组件,配置各不相同,尽量使用下面方式逐一检查。

    1.根据使用的技术栈,查看官方的指导,检验是否有变动

    根据关键字搜索github中官方文档(https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide),示例,redis相关:

    image.png

    目前使用的常用中间件需要关注的信息:

    数据库: mysql、数据库连接池
    搜索引擎: elasticsearch
    nosql: redis
    mq: rabbitmq、kafka

    2.检查配置变化

    配置变动的情况有

    1.属性key变化。
    2.属性value默认值有变化。
    3.属性value单位发生变化。 例如:server.connection-timeout=10需要写成server.connection-timeout=10ms

    (1)根据已有的配置,查看官方的指导,检验是否有变动

    根据关键字搜索github中官方文档(https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Configuration-Changelog),示例,服务上下文配置相关:

    image.png

    (2)使用IDEA检验是否正确

    将配置文件(yml、properties格式)拷贝到IDEA
    示例:
    springboot的自动化配置中,不包含spring.application.names属性,所以会标注警告信息

    image.png

    2.解决包依赖的版本冲突

    包冲突的后果:

    1. 编译报错
    2. 项目无法正常启动,因为类结构可能有变化
    3. 项目可启动,运行中项目程序出错,因为有些类运行时才能执行

    解决办法:
    查看包依赖的版本,exclude包或者删除包依赖。注意:并非排除了冲突的包就能解决问题,因为可能解决了A代码缺少的类,但是导致了B代码缺失了类。

    IDEA安装maven-helper插件,找到xxx-service模块的pom.xml文件

    image.png

    三、常见的改变汇总

    1.应用上下文路径

    server.context-path改为server.servlet.context-path

    2.eureka和feign的坐标变化

    (1)feign

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-feign</artifactId>
    </dependency>  
    

    改为

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency> 
    

    @FeignClient和@EnableFeignClients包名变了,需要重新import

    (2)eureka-client

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency> 
    

    改为

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    

    (3)eureka-server

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
    

    改为

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    

    (4)hystrix

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>
    

    改为

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    

    3.feign调用超时设置

    1.5.9.RELEASE

    ribbon.ReadTimeOut=10000
    ribbon.ConnectTimeout=10000
    

    2.x.RELEASE

    feign.client.default.readTimeout=10000 feign.client.default.connectTimeout=10000
    

    参考:Spring Cloud组件那么多超时设置,如何理解和运用? https://www.jianshu.com/p/c836a283631e

    4.log4j2

    我们使用的日志组件是log4j2

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

    springboot-1.5.9.RELEASE版本的log4j2版本是2.7,而2.x以上版本至少是2.10.0版本

    5.数据库连接池

    springboot-1.5.9.RELEASE版本默认连接池用的是tomcat-jdbc,2.x版本用的是性能更好的HikariCP连接池

    springboot-1.5.9.RELEASE版本,用spring.datasource.tomcat开头的参数配置连接池,示例

    ### 数据库连接配置
    spring.datasource.tomcat.test-on-borrow = false
    spring.datasource.tomcat.test-while-idle = true
    spring.datasource.tomcat.time-between-eviction-runs-millis = 3600000
    spring.datasource.tomcat.max-active=30
    

    springboot-2.x.RELEASE版本,用spring.datasource.hikari开头的参数配置连接池,示例

    ### 数据库连接配置
    # 最小空闲连接数,默认是10
    spring.datasource.hikari.minimum-idle=5
    ## 连接池最大连接数,默认是10
    spring.datasource.hikari.maximum-pool-size=15
    

    可参考官方配置:https://github.com/brettwooldridge/HikariCP

    注意
    1.HikariCP的作者推荐使用hikaricp的默认配置即可,因为作者对连接池的默认配置是经过大量优化得出的。如果有特殊的情况,可参考作者的建议:https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing

    2.重要:不推荐只设置maximum-pool-size而不设置minimum-idle,因为maximum-pool-size一般是用来提供给突然的高并发而设置的。但如果当设置maximum-pool-size,而没有设置minimum-idle,系统会自动设置minimum-idle=maximum-pool-size,这样会导致应用从启动开始,一直保持maximum-pool-size大小的数据库连接,如果应用本不需要这么多连接,会浪费连接,而导致数据库连接数不够用。

    6.上传附件的大小控制配置

    spring.http.multipart.max-file-size=20mb spring.http.multipart.max-request-size=30mb
    

    改为

    spring.servlet.multipart.max-file-size=20mb spring.servlet.multipart.max-request-size=30mb
    

    7.redis客户端

    # boot1.x配置
    spring:
      datasource:
      redis:
        database: 0 # Database index used by the connection factory.
        timeout: 0 # Connection timeout in milliseconds.
        pool:  # 默认使用jedis客户端
          max-active: 8 #
          max-idle: 8 # 
          max-wait: -1 # 
          min-idle: 1 # 
    
    #boot2.x配置
    spring:
      redis:
        database: 0 # Database index used by the connection factory.
        timeout: 0 # Connection timeout in milliseconds.
        lettuce: # 默认使用lettuce客户端,如果需要使用jedis客户端,需要修改pom.xml
          pool:
            max-active: 8 # 
            max-idle: 8 # 
            max-wait: -1 # 
            min-idle: 1 # 
    

    如果需要改为jedis客户端,需要配置pom.xml

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <!-- 1.5的版本默认采用的连接池技术是jedis  2.0以上版本默认连接池是lettuce, 在这里采用jedis,所以需要排除lettuce的jar -->
        <exclusions>
            <exclusion>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
            </exclusion>
            <exclusion>
                <groupId>io.lettuce</groupId>
                <artifactId>lettuce-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!--spring2.0集成redis所需common-pool2-->
    <!-- 必须加上,jedis依赖此  -->
    <!-- spring boot 2.0 的操作手册有标注 大家可以去看看 地址是:https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/-->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.5.0</version>
    </dependency>        
    

    8.eureka注册中心

    eureka的server与client采用http方式通信,所以eureka的server可以不用升级,但最好server一起升级,方便未来进行扩展。

    未来会换用consul注册中心,因为eureka已经停止维护并且偶尔有异常报错的情况。

    9.监控检查地址

    如果依赖了spring-boot-actuator

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

    原来的健康检查地址有变动,最常用的/info和/health已改为/actuator/info和/actuator/health.

    影响:
    应用监控的健康检查策略如果是:如果配置的是/info或者/health,需要修改为新的地址,不然应用启动后后,探针访问/info或/health地址后会报404,认为是启动失败。

    四、建议

    1.尽量早做,在项目迭代中预留足够的测试时间,升级的坑可能要测试较长一段时间后才能发现。

    2.后端开发修改完配置后,要评估影响范围,并告知测试人员,一起进行回归测试。

    相关文章

      网友评论

        本文标题:SpringBoot1.x升级到2.x实践

        本文链接:https://www.haomeiwen.com/subject/zqcjdhtx.html