SpringCloud 之動態刷新、重試、服務化

假如說我們的配置從遠程倉庫獲取失敗了,那麼該如何去處理呢?這裏就要使用到 Spring Cloud Config 爲我們提的動態刷新重試功能了,Spring Cloud Config 是服務化的。那麼什麼是服務化呢?

服務化

我們在前面的配置中,當 Config Client 需要從 Config Server 上獲取配置數據時,我們都是直接在 Config Client 的配置文件中寫上 Config Server 的地址,類似下面這種架構:

在這裏插入圖片描述
這種寫法相當於將 Config Client 和 Config Server 綁定死了,以後 Config Server 的地址不能變,Config Server 也不能掛,否則 Config Client 就獲取不到信息了,而且這種方式也破壞了我們微服務的整體架構,即服務之間互相調用,獲取對方的信息都是去服務註冊中心上獲取,所以我們要對這種結構進行改造,改造成下面這種結構:
在這裏插入圖片描述
當 Config Server 啓動時,將自己註冊到服務註冊中心 Eureka 上,所有 Config Client 都從 Eureka 上去獲取 Config Server 的信息,這樣我們就成功將 Config Server 和 Config Client 解耦了,Eureka 在這裏依然扮演了數據中心的角色。

那麼下面我們來演示如何服務化,大家可以根據上一篇的例子進行改造。當然也可以再創建一個項目來實現。這裏我選擇重新創建來帶着大家來搭建。

首先我們依然是創建一個cloudConfig-fwh普通maven工程來作爲父工程。然後再從cloudConfig-fwh中創建一個普通的文件夾configRepo來存放github配置文件,然後再分別創建eureka、config_server、config_client。

創建好後,項目結構如下:
在這裏插入圖片描述
然後我們分別將config_client 和 config_server 註冊到eureka實例上。

在這裏插入圖片描述
我們訪問localhost:7000 發現已經註冊上去了。

那麼我們還需要對Config Client配置,這裏我們在bootstrap.yml中配置,bootstrap.yml優先級比application.yml高,spring cloud config 優先配置都會放在這裏:
bootstrap.yml 配置如下:

spring:
  application:
    name: config-server
  # 本地配置
  # profiles:
  #   active: native
  cloud:
    config:
      profile: dev
      label: master
      discovery:
        service-id: config-server3
        enabled: true
server:
  port: 8002
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7000/eureka/

這裏新增的兩個配置我說一下,其中discovery.service-id 代替了原來的cloud.config.uri
原來的uri需要寫很長。而且如果ip地址端口號發生了變化,那麼還需要去Config Server去修改,這裏使用了service-id完美瞭解決了這個問題。通過service-id去eureka中心尋找Config Server的實例。discovery.enabled=true 是開啓通過eureka來獲取Config Server。

注意這裏有一個小坑。就是這個spring.application.name的名稱是你在github倉庫的配置文件的前綴如下圖:
在這裏插入圖片描述
這裏取config-server就可以了。

配置好了後,我們訪問http://localhost:8002/love 訪問結果如下:
在這裏插入圖片描述
這樣就訪問成功了,說明我們的配置沒有問題。下面我們來說一下動態刷新。

動態刷新

接下來我們再來看一下配置文件動態刷新的問題,當 Git 倉庫中配置文件發生改變後,如果我們刷新 Config Server 中的請求地址,會發現數據也跟着變化了,即 Config Server 是能夠及時感知到配置文件的變化的,但是這種感知卻不能夠傳遞到 Config Client 中去,即 Config Client 是無法及時感知到配置文件的變化的,默認情況下,只有 Config Client 重啓,才能夠加載到最新的配置文件數據,如何讓 Config Client 也能動態刷新配置數據呢?

我們只需要在Config Client 中加入如下依賴就能動態刷新配置:

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

添加完成後我們還需要對refresh接口暴露,這裏注意,除了G版本的Cloud需要額外手動的暴露refresh接口外,其它版本的Cloud不用配置下面這段配置來進行手動暴露

management:
  endpoints:
    web:
      exposure:
        include: 'refresh'

這裏配置好了後,我們對HelloController增加一個註解@RefreshScope 當調用refresh 接口當時候動態刷新:

@RefreshScope
@RestController
public class HelloController {
    @Value("${love}")
    String love;

    @GetMapping("/love")
    public String name() {
        return love;
    }
}

配置好了後,我們重啓Config Client項目,然後可以看到idea的控制檯/actuator/refresh接口已經暴露出來了。
在這裏插入圖片描述
這個接口用來動態刷新配置文件。

當然配置好了這個動態刷新接口,我們肯定要訪問來測試下。接口是否正常。
我們訪問http://localhost:8002/actuator/refresh 注意這裏使用post請求訪問,如果如下圖一樣就說明接口正常:
在這裏插入圖片描述
但細心的人可能這裏會發現一個問題,不重啓Config Client的情況下,也能實現動態刷新配置,但是所有的微服務都要一個個的去發送/actuator/refresh 接口請求,很麻煩,那麼有什麼簡便的方式呢?肯定是有的下面我會介紹。

請求失敗重試

請求失敗了肯定要重試啊,不可能失敗了,就讓它一直失敗。這肯定是不行的。細心的朋友看過我之前的文章的話,我是講了如何失敗重試的,比如網絡的波動,當網絡質量很差的情況下,就會導致服務調用的失敗。那麼我們就要做到請求失敗了,就要重試。

要實現失敗重試也是非常簡單的,之前看過我文章的朋友,肯定知道這裏需要加兩個依賴:

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

加上這個依賴後,我們需要在Config Client 的bootstrap.yml中加入如下配置:

fail-fast: true

這個配置的意思是失敗快速響應,在默認情況下 我們的Config Client 去訪問Config Server 失敗時候,並不會馬上報錯 而是要等到使用到Config Server 的某個數據的時候纔會報錯,通俗的意思就是我們之前不是有個love變量嗎?如果這個love變量並不存在,而我們的Config Client又在調用使用的話,那麼就會報錯並拋出異常。所以當我們的Config Client 訪問 Config Server 失敗的時候,就要開啓快速響應,這裏可以是失敗重試,也可以拋出自定義異常信息。

添加完這個配置之後,爲了演示執行效果,接下來我們再做一點點修改,由於目前我們的 Config Server 是有安全認證的,Config Client 必須要有用戶名密碼才能訪問到 Config Server 中的數據。我們暫時先註釋掉 Config Client 中訪問 Config Server 的用戶名密碼,即如下兩行:

#spring:
#  cloud:
#    config:
#      username: jishu
#      password: 123456

這裏的username 和 password 是在Config Server 中配置的Security的賬戶密碼信息,這裏我們註釋掉後,重啓Config Client 項目,我們來看下失敗重試的效果:
在這裏插入圖片描述
可以看到,一共發了6次請求,第一失敗後,還繼續重試了5次,這就是默認的請求策略,我們可以配置請求策略:

spring:
  cloud:
    config:
      retry:
        initial-interval: 1000
        multiplier: 1.1
        max-interval: 2000

這四個配置解釋如下:

  1. max-attempts 表示最大請求次數,默認值爲 6 ,就是大家在上圖看到的情況
  2. initial-interval 表示請求重試的初始時間間隔
  3. multiplier 表示時間的間隔乘數,由於網絡抖動一般都是有規律的,爲了防止請求重試時連續的衝突,我們需要一個時間間隔乘數,這裏我設置了間隔乘數爲 1.2 ,表示第一次重試間隔時間爲 1 s,第二次間隔時間爲 1.2 秒,第三次間隔時間爲 1.44 秒…
  4. max-interval 表示重試的最大間隔時間

開啓了請求重試機制之後,即使在弱網環境下,我們也能有效保證服務的可用性。

總結

本文主要向大家介紹了分佈式配置中心 Spring Cloud Config 中三個常見的問題,服務化、配置數據動態刷新以及請求失敗重試。服務化降低了 Config Server 和 Config Client 之間的耦合度,使我們的項目架構更加規範;動態刷新則讓我們在不重啓 Config Client 的情況下,能夠刷新配置數據;最後的請求重試則保證了弱網環境下服務的可用性,在實際生產項目中,這三個基本上也都是必配的,大家需要認真掌握。

項目地址

github

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章