1. 程式人生 > >Spring Cloud 升級Finchley.SR2穩定版本詳細方案(雙12福利)

Spring Cloud 升級Finchley.SR2穩定版本詳細方案(雙12福利)

                                 升級攻略

1.升級必讀                           

當我們決定升級SpringCloud的時候,首先要考慮的第一個問題是什麼?

自然不用說,那肯定是SpringCloud的主版本的問題,是要升級到什麼版本,是F版還是G版本

這裡給幾點建議(親採坑經驗)

企業開發用Finchley.SR2(穩定版本),個人開發隨意。

升級的時候用的是Greenwish M3 pre最新版本(需要配置maven地址配成Spring提供的倉庫地址,暫時沒有提交到其他倉庫)可是遇到了很多問題,最要命的是bug不好找解決方案。不到半天的時間就降為了F穩定版本。

SpringCloud 版本說明

下圖是在官網一個關於SpringCloud版本的說明(截至2018年12月 12日)希望能幫助您

cloud版本 SNAPSHOT: 快照版本,隨時可能修改 ;
M: MileStone;M1表示第1個里程碑版本,一般同時標註PRE,表示預覽版版;
SR: Service Release,SR1表示第1個正式版本,一般同時標註
GA:(GenerallyAvailable),表示穩定版本
所以企業開發選擇穩定版本吧即可,無需猶豫(特殊情況除外) 。更多資訊關注 @架構師速成記

 

2 詳細步驟

2.1合併svn版本,做好備份工作

提交個人程式碼,合併到svn主版本上,做好備份工作後在進行升級(升級肯定有坑點,所以備份是必須的)

 2.2 pom檔案升級

之前版本

啟動之前版本&&升級前 pom檔案

pom檔案

開始升級 父pom檔案升級

 <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

做完兩個引入就升級完了?NO,因為F版本和之前的D版本區別還是很大的,所以尼懂得,繼續下一步。

子模組各個pom需要升級的引入jar(版本變動,引入也變化很大,如eureka、feign等)

eureka

<!--eureka-server服務端引入 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>

feign

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

zuul

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

....其它的元件根據使用者引入做成相應更改,不再一 一列出。

以上幾個元件都發生了變化,所以進行更正為對應版本的引入即可

 

2.3 Java類排查導包問題

jar版本發生了變化,自然下一就是更改java類匯入的包路徑,要不然一路標紅

如feign的 引入 

去除錯誤的引入後重新引入  :import org.springframework.cloud.netflix.feign.FeignClient;

java的問題還是挺多的,根據報錯地方進行排查即可,這些都是比較明顯的問題,比較容易排查,下面列一下比較隱晦的bug。如下所示。 如果對您的專案有幫助歡迎關注  @架構師速成記

3.常見 問題彙總

 

3.1、Eureka 註冊中心顯示服務的ip地址不顯示

問題描述:   如下圖所示註冊 中心不顯示服務的ip地址了,尷尬了

UP (1) - ${spring.cloud.client.ipAddress}:7006

解決方案:

eureka:
  client: #客戶端註冊進eureka服務列表內
    service-url:
     defaultZone: http://localhost:7001/eureka/
  instance:
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}
    prefer-ip-address: true 

將${spring.cloud.client.ipAddress}改成${spring.cloud.client.ip-address}

eureka:
  client: #客戶端註冊進eureka服務列表內
    service-url:
     defaultZone: http://localhost:7001/eureka/
  instance:
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    prefer-ip-address: true 

3.2、zuul閘道器集合springsecurity_JWT 頒發token_但是Authorization無法傳遞到response的header中

1.預設情況下,zuul不會將敏感的http首部,如(Cookie,Set-Cookie)和Authorization轉發到下游服務,要讓Zuul傳播HTTP首部Authorization,需要在zuul服務閘道器的application.yml或者application.properties中,設定以下配置:

這樣設定:

E:\IdeaWkSpace\SmartCommunity\sc-gateway\src\main\resources\application.properties

spring.application.name=sc-gateway
server.port=8040
zuul.host.socket-timeout-millis=60000
zuul.host.connect-timeout-millis=10000
#zuul.routes.api-a.path=/producer/**
#zuul.routes.api-a.url=spring-cloud-producer

#zuul.sensitive-headers="Cookie", "Set-Cookie", "Authorization")
zuul.sensitive-headers="Cookie","Set-Cookie"  //注意這裡就是這樣設定的

上面是提出的一種解決方案,暫時沒有那樣設定,我們採用下面的這種做法

核心思路就是Authorization這種敏感關鍵字用其他如x-user-token代替

//傳遞token的備用欄位
public static final String HEADER_X_USER_TOKEN = "x-user-token";

解決方案:

 String token=  request.getHeader(JwtUtil.HEADER_AUTH);

        log.info("訪問token{}",token);

        //是否開啟 token認證,獲取登陸使用者
        if(!StrUtils.isBlank(token)){
         try {
             UserInfo userInfo=JwtUtil.getInstance().validateToken(token);
             if(!StrUtils.isBlank(userInfo)) {
                 ctx.addZuulRequestHeader(JwtUtil.HEADER_AUTH,token);

                 ctx.addZuulRequestHeader("x-user-id", userInfo.getId());
                 ctx.addZuulRequestHeader(JwtUtil.HEADER_X_USER_TOKEN,token);
//                 ctx.addZuulRequestHeader("x-role-code", request.getRequestURL().toString());
             }
         }catch (Exception ex){

 

public class UserTokenIntercepter extends HandlerInterceptorAdapter {
    private static final Logger log = LoggerFactory.getLogger(UserTokenIntercepter.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse respone, Object arg2) throws Exception {
        String token=  request.getHeader(JwtUtil.HEADER_AUTH);
        //預設情況下,zuul不會將敏感的http首部,如(Cookie,Set-Cookie)和Authorization轉發到下游服務,要讓Zuul傳播HTTP首部Authorization,需要在zuul服務閘道器的application.yml或者application.properties中,設定以下配置:zuul.sensitive-headers="Cookie","Set-Cookie"

        //如果無法傳遞換成其他的欄位傳遞token
        if(StrUtils.isBlank(token)){
            token=  request.getHeader(JwtUtil.HEADER_X_USER_TOKEN);
        }
        //respone.setCharacterEncoding(Constant.CONTENT_TYPE);
        if (!StrUtils.isBlank(token)){
            ApplicationContextHolder.setToken(token);
        }
        return true;
    }

3.3、跨域問題

問題描述
前端 vue 框架,後臺 php,百度跨域問題後臺加這段程式碼 
header("Access-Control-Allow-Origin: *");

加了之後報這個錯: 
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

引用網上比較常見的討論,截圖如下

在升級之前因為需要驗證碼 保持session一致性,所以配置withCredentials是true的,但是升級之後,問題就出現來了,後來用下面的這段配置解決 了升級的問題,程式碼如下。如果對你的專案有幫助歡迎關注今日頭條 @架構師速成記

@Configuration
public class WebMvcFilterConfigurerAdapter implements WebMvcConfigurer {
    /**
     * 解決跨域的問題
     * @return
     */
 @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // 允許cookies跨域
        config.addAllowedOrigin("*");// #允許向該伺服器提交請求的URI,*表示全部允許,在SpringMVC中,如果設成*,會自動轉成當前請求頭中的Origin
        config.addAllowedHeader("*");// #允許訪問的頭資訊,*表示全部
        config.setMaxAge(18000L);// 預檢請求的快取時間(秒),即在這個時間段裡,對於相同的跨域請求不會再預檢了
        config.addAllowedMethod("*");// 允許提交請求的方法,*表示全部允許
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
...
}

 

3.4 WebMvcConfigurerAdapter過時問題

解決思路:用WebMvcConfigurer替代

@Configuration
public class WebMvcFilterConfigurerAdapter implements WebMvcConfigurer {
    @Bean
    public HandlerInterceptor getSecurityInterceptor(){
        return new SecurityInterceptor();
    }
    /**
     * 配置靜態資源
     */
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        registry.addResourceHandler("/templates/**").addResourceLocations("classpath:/templates/");
//        super.addResourceHandlers(registry);
    }
.....
}

 

3.5 Feign報錯'xx.FeignClientSpecification', defined in null, could not be registered.

錯誤描述:

版本使用的是SpringBoot: 2.0.6.RELEASE,SpringCloud: F穩定版
報錯:

The bean 'xxxx.FeignClientSpecification', defined in null, could not be registered. 
A bean with that name has already been defined in null and overriding is disabled.

Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: 
Invalid bean definition with name xxxx.FeignClientSpecification' defined in null: 
Cannot register bean definition [Generic bean: class [org.springframework.cloud.openfeign.FeignClientSpecification]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] for bean 'xxxx.FeignClientSpecification': There is already [Generic bean: class [org.springframework.cloud.openfeign.FeignClientSpecification]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] bound.

解決:多個介面上的@FeignClient(“相同服務名”)會報錯,overriding is disabled

在application.yml中配置:

spring:
  main:
    allow-bean-definition-overriding: true

暫時 這麼解決,不知有沒有“後患”,歡迎其他人留言,共同討論,謝謝。

3.6 .Error:(4, 40) java: 程式包com.fasterxml.jackson.annotation不存在
 <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
3.7 .Caused by: java.lang.IllegalStateException: Failed to introspect Class [com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure] from ClassLoader [[email protected]
將druid升級到1.1.10


3.8 Servlet-specific server properties

A number of server.* properties that are Servlet-specific have moved to server.servlet:

Old property New property

server.context-parameters.*

server.servlet.context-parameters.*

server.context-path

server.servlet.context-path

server.jsp.class-name

server.servlet.jsp.class-name

server.jsp.init-parameters.*

server.servlet.jsp.init-parameters.*

server.jsp.registered

server.servlet.jsp.registered

server.servlet-path

server.servlet.path

3.9 Endpoints infrastructure key have been harmonized:

Old property New property

endpoints.<id>.*

management.endpoint.<id>.*

endpoints.cors.*

management.endpoints.web.cors.*

endpoints.jmx.*

management.endpoints.jmx.*

management.address

management.server.address

management.context-path

management.server.servlet.context-path

management.ssl.*

management.server.ssl.*

management.port

management.server.port

3.10 Developer Tools

Hot swapping

As the Spring Loaded project has been moved to the attic, its support in Spring Boot has been removed. We advise to use Devtools instead.

Devtools Remote Debug Tunnel

The support for tunnelling remote debugging over HTTP has been removed from Devtools.

總的來說熱部署外掛注意下 就ok

3.11 Dependency Versions(版本依賴)

The minimum supported version of the following libraries has changed:

  • Elasticsearch 5.6

  • Gradle 4

  • Hibernate 5.2

  • Jetty 9.4

  • Spring Framework 5

  • Spring Security 5

  • Spring Integration 5 (see also their migration guide)

  • Tomcat 8.5

Spring Boot 2.x 新特性總結及遷移指南(轉) 

https://blog.csdn.net/zzhuan_1/article/details/84975942

3.12 springboot2.x 的 RedisCacheManager變化

RedisCacheManager已經沒有了單引數的構造方法 

....

END

還有 其他問題暫時沒有 彙總完,下一章節進行彙總,如果對您的專案有幫助歡迎關注 @架構師速成記