Spring cloud系列十八 Spring Cloud 從Dalston.SR5到Greenwich.SR1 的升級記錄

背景

項目以前一直使用Spring Cloud Dalston.SR5,可是此版本2018年12月軟件生命週期要結束,爲了後續安全和維護的須要,須要將對版本進行升級。先從官網上分析D版本的後續版本的變動,發現大部分組件基本是兼容的,這裏只列出對升級有重大影響的部分變化:java

  • Edgware:依賴的spring boot版本升級仍然是1.5, 許多組件的名稱變化
  • Finchley:依賴的spring boot版本升級到2.0,真正的大版本升級,重大變化
  • Greenwich:依賴的spring boot版本升級到2.1,支持java11

而後咱們再搜索網上其它人升級的經驗和難度,最後決定將目前的spring cloud直接升級最新版本:Greenwich.SR1git

升級的詳細步驟和碰到的坑

spring-cloud-dependencies版本從Dalston.SR5到Greenwich.SR1

<artifactId>spring-cloud-dependencies</artifactId>
	<version>Dalston.SR5</version>
	-->
	<artifactId>spring-cloud-dependencies</artifactId>
	<version>Greenwich.SR1</version>
複製代碼

spring boot 版本從1.5.13 升級到2.1.4

<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.13.RELEASE</version>
--> 
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
複製代碼

spring cloud的組件的artifactId名稱變動: 左邊是舊,右邊是新的

spring-cloud-starter-eureka --> spring-cloud-starter-netflix-eureka-client
spring-cloud-starter-eureka-server  -->  spring-cloud-starter-netflix-eureka-server
spring-cloud-starter-feign --> spring-cloud-starter-openfeign
spring-cloud-starter-hystrix -> spring-cloud-starter-netflix-hystrix
複製代碼

將pom.xml中對應的artifactId名稱修改成最新的名稱 其它artifactId部分修改見這裏:E版本 github.com/spring-proj…github

Feign的變化

feign除了上面提到組件的artifactId名稱重名爲 spring-cloud-starter-openfeign外,還有如下部分發生變化:redis

包名發生改變:spring

org.springframework.cloud.netflix.feign.**.java -> org.springframework.cloud.openfeign.**.java
複製代碼

@FeignClient增長一個屬性值contextId 以前的版本若是有存在兩個name屬性相同@FeignClient對象,不會報錯,可是升級後,會將相同name屬性的實例對象認爲是同一個Bean從而拋出以下異常: "The bean 'icc-authority.FeignClientSpecification', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled."apache

解決方案是在@FeignClient註解裏增長contextId值將爲bean id,以下:tomcat

@FeignClient(name="authority", fallbackFactory = IAccountServiceFallbackFactory.class, contextId = "accountService")
	public interface IAccountService {
		
	}
複製代碼

Feign鏈接池 因爲Spring Cloud D版本的Fegin使用httpclient作鏈接池,默認建立鏈接池對象的可配置項太少且鏈接池中可能存在處於半鏈接狀態的鏈接(關於httpclient半鏈接狀態bug見這篇文章 ),因此本身實現了HttpClient實例。到了G版本,若是實現Httpclient作鏈接池則,默認使用系統本身建立的httpclient對象,另外觀察源碼HttpClientFeignLoadBalancedConfiguration 建立 httpclient的代碼,不只增長定時器關閉異常的鏈接解決半鏈接的問題,鏈接池的參數都是可配置的。 安全

在這裏插入圖片描述

解決方案: 方案一. 因此去除本身的httpclient實例,使用默認的httpclient實例 方案二. 因爲默認實現httpclient依然有部分參數不自由配置,咱們仍然能夠繼續使用本身的httpclient,在建立httpclient的方法上標記@Primay,且方法名稱不能夠爲httpclient,不然會報錯bash

@Bean
    @Primary
    public HttpClient httpClientDefault(FeignHttpClientPoolConfiguration feignHttpClientPoolConfiguration){
        HttpClient httpClient = ….;
        return httpClient;
    }
複製代碼

Spring Cloud Feign的文件上傳實現的依賴jar包的升級 若是有使用feign實現文件上傳,則會拋出以下異常: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found 解決方法: io.github.openfeign.form.feign-form和io.github.openfeign.form.feign-form-spring從3.0.3 版本升級到 3.8.0 commons-fileupload升級到1.4curl

沒法找到jedis相關的組件

新版本使用Spring Data Redis 2.0,此版本已經將將jedis移除,默認使用的 Lettuce組件 解決方案一: 不使用jedis,直接升級到使用Lettuce,若是代碼中沒有顯示使用jedis,建議使用此方案 而後對redis配置參數根據ide的提示修改便可 解決方案二: 增長jedis依賴

<dependency>
		        <groupId>redis.clients</groupId>
		        <artifactId>jedis</artifactId>
		        <version>2.9.0</version>
		</dependency>
複製代碼

Druid鏈接池版本升級

拋出異常:Caused by: java.lang.ClassNotFoundException: org.apache.log4j 緣由:新版本Spring Boot不要使用log4j,可是支持log4j2 解決方法: 1. 配置drui的屬性filters值爲log4j2: 2. 升級com.alibaba.druid.jar包升級到1.1.16

分佈插件pagehelper 升級:

異常:pagehelper 沒法正常工做 緣由:當前的使用pagehelper-spring-boot-starter 不支持spring boot 2.1.x 解決方案: 1. com.github.pagehelper: pagehelper-spring-boot-starter 升級到 1.2.10, 用於支持spring boot 2.1.x 2. 對應的 com.github.pagehelper: pagehelper 升級到5.1.8

屬性配置的變化:

應用的上下文路徑:server.context-path: authority --> server.servlet.context-path: authority 上傳文件參數配置:spring.http.multipart.* -> spring.servlet.multipart.* 如原 spring.http.multipart.maxFileSize:5Mb -> spring.servlet.multipart.maxFileSize:5MB 同時這裏5Mb中的Mb的必須是大寫字母,必須是5MB,不然會拋出異常:failed to convert java.lang.String to @org.springframework.boot.convert.DataSizeUnit org.springframework.util.unit.DataSize

@NotBlank, @NotEmpty 註解已經歸入了JSR303,不須要在使用hibernate提供的註解了

org.hibernate.validator.constraints.NotBlank --> javax.validation.constraints.NotBlank org.hibernate.validator.constraints.NotEmpty --> javax.validation.constraints.NotEmpty

zipkin

在新的版本中,@EnableZipkinServer已經被標記@Deprecated,已經不推薦自行定製編譯服務的方式運行zipkin。官方推薦下載jar直接運行 curl -sSL zipkin.io/quickstart.… | bash -s java -jar zipkin.jar 詳細見這裏: github.com/apache/incu… github.com/apache/incu…

其它:

在升級後,常常拋出沒有找到類的異常:java.lang.NoClassDefFoundError 對於這類錯誤,經過只要找到對應的jar將其升級到最新的版本就能夠解決。 這也告訴咱們若是要使用第三方的組件,必定要使用社區活躍的組件,不然一旦此組件出現安全問題或系統升級版本時,此組件不兼容其它的組件,則必需要使用新組件替換此組件的功能。

版本升級後會有deprecated的類或方法,因此要注意看console中build的warning信息 因爲咱們使用的Spring Cloud最近的版本,升級依賴jar一般只要升級到最新版本基本沒問題

Spring Cloud Netflix 進入項目進入維護模式階段

Spring Cloud Netflix 除了spring-cloud-netflix-eureka-* 和spring-cloud-netflix-concurrency-limits 模塊之外,所有進入維護模式,詳細以下: ○ spring-cloud-netflix-archaius ○ spring-cloud-netflix-hystrix-contract ○ spring-cloud-netflix-hystrix-dashboard ○ spring-cloud-netflix-hystrix-stream ○ spring-cloud-netflix-hystrix ○ spring-cloud-netflix-ribbon ○ spring-cloud-netflix-turbine-stream ○ spring-cloud-netflix-turbine ○ spring-cloud-netflix-zuul

如下表中左邊的模塊也已經進入維護模塊,右邊是他的未來替代者

  • Hystrix已經進入維護模式,建議使用Resillence4j替換,對應的Hystrix Dashboard和Turbine也會被淘汰,建議使用Resillence4j自帶Micrometer進行替換。 Resillence4j的孵化地址:github.com/spring-clou…
  • Ribbion被Spring Cloud Loadbalancer替換,孵化地址:github.com/spring-clou…
  • Zuu1 1 被 Spring Cloud GateWay替換: 有Spring Cloud Gateway和Zuul 1.x的性能對比:www.itmuch.com/spring-clou…
  • Archaius 1的替代Spring Boot external config + Spring Cloud Config

什麼是維護模式:Spring Cloud 不會向對應的模塊增長新的功能,可是他們仍然會修復出現的bug和安全問題,以及接受社區的pull request。 即便Greenwich版本被廣泛採用後,Spring Cloud仍然保證會繼續支持以上的模塊至少一年

相關文章
相關標籤/搜索