SpringCloud之動態(tài)刷新、重試、服務化的實現(xiàn)
假如說我們的配置從遠程倉庫獲取失敗了,那么該如何去處理呢?這里就要使用到 Spring Cloud Config 為我們提的動態(tài)刷新重試功能了,Spring Cloud Config 是服務化的。那么什么是服務化呢?
服務化
我們在前面的配置中,當 Config Client 需要從 Config Server 上獲取配置數(shù)據(jù)時,我們都是直接在 Config Client 的配置文件中寫上 Config Server 的地址,類似下面這種架構:
這種寫法相當于將 Config Client 和 Config Server 綁定死了,以后 Config Server 的地址不能變,Config Server 也不能掛,否則 Config Client 就獲取不到信息了,而且這種方式也破壞了我們微服務的整體架構,即服務之間互相調(diào)用,獲取對方的信息都是去服務注冊中心上獲取,所以我們要對這種結構進行改造,改造成下面這種結構:
當 Config Server 啟動時,將自己注冊到服務注冊中心 Eureka 上,所有 Config Client 都從 Eureka 上去獲取 Config Server 的信息,這樣我們就成功將 Config Server 和 Config Client 解耦了,Eureka 在這里依然扮演了數(shù)據(jù)中心的角色。
那么下面我們來演示如何服務化,大家可以根據(jù)上一篇的例子進行改造。當然也可以再創(chuàng)建一個項目來實現(xiàn)。這里我選擇重新創(chuàng)建來帶著大家來搭建。
首先我們依然是創(chuàng)建一個cloudConfig-fwh普通maven工程來作為父工程。然后再從cloudConfig-fwh中創(chuàng)建一個普通的文件夾configRepo來存放github配置文件,然后再分別創(chuàng)建eureka、config_server、config_client。
創(chuàng)建好后,項目結構如下:
然后我們分別將config_client 和 config_server 注冊到eureka實例上。
我們訪問localhost:7000
發(fā)現(xiàn)已經(jīng)注冊上去了。
那么我們還需要對Config Client配置,這里我們在bootstrap.yml中配置,bootstrap.yml優(yōu)先級比application.yml高,spring cloud config 優(yōu)先配置都會放在這里:
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地址端口號發(fā)生了變化,那么還需要去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
訪問結果如下:
這樣就訪問成功了,說明我們的配置沒有問題。下面我們來說一下動態(tài)刷新。
動態(tài)刷新
接下來我們再來看一下配置文件動態(tài)刷新的問題,當 Git 倉庫中配置文件發(fā)生改變后,如果我們刷新 Config Server 中的請求地址,會發(fā)現(xiàn)數(shù)據(jù)也跟著變化了,即 Config Server 是能夠及時感知到配置文件的變化的,但是這種感知卻不能夠傳遞到 Config Client 中去,即 Config Client 是無法及時感知到配置文件的變化的,默認情況下,只有 Config Client 重啟,才能夠加載到最新的配置文件數(shù)據(jù),如何讓 Config Client 也能動態(tài)刷新配置數(shù)據(jù)呢?
我們只需要在Config Client 中加入如下依賴就能動態(tài)刷新配置:
<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
當調(diào)用refresh
接口當時候動態(tài)刷新:
@RefreshScope @RestController public class HelloController { @Value("${love}") String love; @GetMapping("/love") public String name() { return love; } }
配置好了后,我們重啟Config Client項目,然后可以看到idea的控制臺/actuator/refresh
接口已經(jīng)暴露出來了。
這個接口用來動態(tài)刷新配置文件。
當然配置好了這個動態(tài)刷新接口,我們肯定要訪問來測試下。接口是否正常。
我們訪問http://localhost:8002/actuator/refresh
注意這里使用post請求訪問,如果如下圖一樣就說明接口正常:
但細心的人可能這里會發(fā)現(xiàn)一個問題,不重啟Config Client的情況下,也能實現(xiàn)動態(tài)刷新配置,但是所有的微服務都要一個個的去發(fā)送/actuator/refresh
接口請求,很麻煩,那么有什么簡便的方式呢?肯定是有的下面我會介紹。
請求失敗重試
請求失敗了肯定要重試啊,不可能失敗了,就讓它一直失敗。這肯定是不行的。細心的朋友看過我之前的文章的話,我是講了如何失敗重試的,比如網(wǎng)絡的波動,當網(wǎng)絡質(zhì)量很差的情況下,就會導致服務調(diào)用的失敗。那么我們就要做到請求失敗了,就要重試。
要實現(xiàn)失敗重試也是非常簡單的,之前看過我文章的朋友,肯定知道這里需要加兩個依賴:
<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 的某個數(shù)據(jù)
的時候才會報錯
,通俗的意思就是我們之前不是有個love變量嗎?如果這個love變量并不存在,而我們的Config Client又在調(diào)用使用的話,那么就會報錯并拋出異常。所以當我們的Config Client 訪問 Config Server 失敗的時候,就要開啟快速響應,這里可以是失敗重試,也可以拋出自定義異常信息。
添加完這個配置之后,為了演示執(zhí)行效果,接下來我們再做一點點修改,由于目前我們的 Config Server 是有安全認證的,Config Client 必須要有用戶名密碼才能訪問到 Config Server 中的數(shù)據(jù)。我們暫時先注釋掉 Config Client 中訪問 Config Server 的用戶名密碼,即如下兩行:
#spring: # cloud: # config: # username: jishu # password: 123456
這里的username 和 password 是在Config Server 中配置的Security的賬戶密碼信息,這里我們注釋掉后,重啟Config Client 項目,我們來看下失敗重試的效果:
可以看到,一共發(fā)了6次請求,第一失敗后,還繼續(xù)重試了5次,這就是默認的請求策略,我們可以配置請求策略:
spring: cloud: config: retry: initial-interval: 1000 multiplier: 1.1 max-interval: 2000
這四個配置解釋如下:
- max-attempts 表示最大請求次數(shù),默認值為 6 ,就是大家在上圖看到的情況
- initial-interval 表示請求重試的初始時間間隔
- multiplier 表示時間的間隔乘數(shù),由于網(wǎng)絡抖動一般都是有規(guī)律的,為了防止請求重試時連續(xù)的沖突,我們需要一個時間間隔乘數(shù),這里我設置了間隔乘數(shù)為 1.2 ,表示第一次重試間隔時間為 1 s,第二次間隔時間為 1.2 秒,第三次間隔時間為 1.44 秒…
- max-interval 表示重試的最大間隔時間
開啟了請求重試機制之后,即使在弱網(wǎng)環(huán)境下,我們也能有效保證服務的可用性。
總結
本文主要向大家介紹了分布式配置中心 Spring Cloud Config 中三個常見的問題,服務化、配置數(shù)據(jù)動態(tài)刷新以及請求失敗重試。服務化降低了 Config Server 和 Config Client 之間的耦合度,使我們的項目架構更加規(guī)范;動態(tài)刷新則讓我們在不重啟 Config Client 的情況下,能夠刷新配置數(shù)據(jù);最后的請求重試則保證了弱網(wǎng)環(huán)境下服務的可用性,在實際生產(chǎn)項目中,這三個基本上也都是必配的,大家需要認真掌握。
項目地址
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Java實現(xiàn)將數(shù)字日期翻譯成英文單詞的工具類實例
這篇文章主要介紹了Java實現(xiàn)將數(shù)字日期翻譯成英文單詞的工具類,結合完整實例形式分析了Java日期轉(zhuǎn)換與字符串操作相關實現(xiàn)技巧,需要的朋友可以參考下2017-09-09java 中Executor, ExecutorService 和 Executors 間的不同
這篇文章主要介紹了java 中Executor, ExecutorService 和 Executors 間的不同的相關資料,需要的朋友可以參考下2017-06-06Springboot集成Actuator監(jiān)控功能詳解
這篇文章主要介紹了Springboot集成Actuator監(jiān)控功能詳解,有時候我們想要實時監(jiān)控我們的應用程序的運行狀態(tài),比如實時顯示一些指標數(shù)據(jù),觀察每時每刻訪問的流量,或者是我們數(shù)據(jù)庫的訪問狀態(tài)等等,這時候就需要Actuator了,需要的朋友可以參考下2023-09-09Java利用Socket實現(xiàn)網(wǎng)絡通信功能
在早期的網(wǎng)絡編程中,Socket是很常見的實現(xiàn)技術之一,比如早期的聊天室,就是基于這種技術進行實現(xiàn)的,另外現(xiàn)在有些消息推送,也可以基于Socket實現(xiàn),本文小編給大家介紹了Java利用Socket實現(xiàn)網(wǎng)絡通信功能的示例,需要的朋友可以參考下2023-11-11IDEA+Maven搭建Spring環(huán)境的詳細教程
這篇文章主要介紹了IDEA+Maven搭建Spring環(huán)境的詳細教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11SpringBoot中Zookeeper分布式鎖的原理和用法詳解
Zookeeper是一個分布式協(xié)調(diào)服務,它提供了高可用、高性能、可擴展的分布式鎖機制,SpringBoot是一個基于Spring框架的開發(fā)框架,它提供了對Zookeeper分布式鎖的集成支持,本文將介紹SpringBoot中的 Zookeeper分布式鎖的原理和使用方法,需要的朋友可以參考下2023-07-07