《Spring Cloud微服務(wù)架構(gòu)進(jìn)階》——2.2 Spring Cloud特性
2.2 Spring Cloud特性

云原生應(yīng)用程序開發(fā)風(fēng)格鼓勵(lì)在持續(xù)交付和價(jià)值驅(qū)動(dòng)開發(fā)上采取最佳的實(shí)踐策略,Spring Cloud提供了多種方式來促進(jìn)云原生開發(fā)風(fēng)格。Spring Cloud提供了一系列組件,可以在分布式系統(tǒng)中直接使用,這些組件大大降低了分布式系統(tǒng)的搭建和開發(fā)難度。
這些組件大多數(shù)由Spring Boot提供,Spring Cloud在此基礎(chǔ)上添加了分布式系統(tǒng)的相關(guān)特性。Spring Cloud依賴于Spring Cloud Context和Spring Cloud Commons兩個(gè)公共庫,其中Spring Cloud Context為Spring Cloud應(yīng)用程序上下文(ApplicationContext)提供了大量的實(shí)用工具和特性服務(wù),而Spring Cloud Common是針對(duì)不同的Spring Cloud實(shí)現(xiàn)(如Spring Cloud Netflix Eureka和Spring Cloud Consul兩種不同的服務(wù)注冊(cè)與發(fā)現(xiàn)實(shí)現(xiàn))提供上層抽象和公共類。
接下來將從這兩個(gè)庫著手,對(duì)Spring Cloud的相關(guān)特性進(jìn)行簡(jiǎn)要介紹。
2.2.1 Spring Cloud Context:應(yīng)用上下文
使用過Spring Boot的讀者都或多或少地了解如何使用Spring構(gòu)建應(yīng)用,比如,配置一般都需要放置在統(tǒng)一的位置,暴露用于管理的網(wǎng)絡(luò)接口等。Spring Cloud在這些最佳實(shí)踐之上提供了新的特性,來適配微服務(wù)架構(gòu)下的運(yùn)維環(huán)境。
1. Bootstrap上下文
除了應(yīng)用上下文配置(application.yml或者application.properties)之外,Spring Cloud 應(yīng)用程序還額外提供與Bootstrap上下文配置相關(guān)的應(yīng)用屬性。Bootstrap上下文對(duì)于主程序來說是一個(gè)父級(jí)上下文,它支持從外部資源中加載配置文件,和解密本地外部配置文件中的屬性。Bootstrap上下文和應(yīng)用上下文將共享一個(gè)環(huán)境(Environment),這是所有Spring應(yīng)用程序的外部屬性來源。一般來講,Bootstrap上下文中的屬性優(yōu)先級(jí)較高,所以它們不能被本地配置所覆蓋。
Bootstrap上下文使用與主程序不同的規(guī)則來加載外部配置。因此bootstrap.yml用于為Bootstrap上下文加載外部配置,區(qū)別于應(yīng)用上下文的application.yml或者application.properties。一個(gè)簡(jiǎn)單的bootstrap.yml的例子如下所示:
spring:
application:
name: my-application
cloud:
config:
uri: ${CONFIG_SERVER:http://localhost:8080}
如果想要禁止Bootstrap引導(dǎo)過程,可以在bootstrap.yml中設(shè)置,如下所示:
spring:
cloud:
bootstrap:
enabled: false
2.應(yīng)用上下文層級(jí)
Spring的上下文有一個(gè)特性:子級(jí)上下文將從父級(jí)中繼承屬性源和配置文件。如果通過SpringApplication或者SpringApplicationBuilder來構(gòu)建應(yīng)用程序上下文,那么Bootstrap上下文將會(huì)成為該應(yīng)用程序上下文的父級(jí)上下文。
在Bootstrap上下文中掃描到的非空的PropertySourceLocators會(huì)以高優(yōu)先級(jí)添加到CompositePropertySource中。如果通過bootstrap.yml來配置Bootstrap上下文,且在設(shè)定好父級(jí)上下文的情況下,bootstrap.yml中的屬性會(huì)添加到子級(jí)的上下文。它們的優(yōu)先級(jí)低于application.yml和其他添加到子級(jí)中作為創(chuàng)建Spring Boot應(yīng)用的屬性源。
基于屬性源的排序規(guī)則,Bootstrap上下文中的屬性優(yōu)先,但是需要注意這些屬性并不包含任何來自bootstrap.yml的數(shù)據(jù)。bootstrap.yml中的屬性具備非常低的優(yōu)先級(jí),因此可以作為默認(rèn)值。
可以簡(jiǎn)單地將父級(jí)上下文設(shè)置為應(yīng)用上下文來擴(kuò)展上下文的層次結(jié)構(gòu)。Bootstrap上下文將會(huì)是最高級(jí)別上下文的父級(jí)。每一個(gè)在層次結(jié)構(gòu)中的上下文都有它自己的Bootstrap屬性源(可能為空),來避免無意中將父級(jí)上下文中的屬性傳遞到它的后代中。層次結(jié)構(gòu)中的每一個(gè)上下文原則上應(yīng)該擁有自己不同的spring.application.name,以便在有配置中心的時(shí)候也能有不同的遠(yuǎn)程屬性源。來自子級(jí)上下文的屬性可以覆蓋父級(jí)中的具有相同名稱和屬性源名稱的屬性。
3.修改Bootstrap配置文件的位置
bootstrap.yml的位置可以通過在配置屬性中設(shè)置spring.cloud.bootstrap.name(默認(rèn)是bootstrap)或者spring.cloud.bootstrap.location來修改。
4.重載遠(yuǎn)程屬性
通過Bootstrap上下文添加到應(yīng)用程序的屬性源通常是遠(yuǎn)程的,例如來自配置中心,通常本地的配置文件不能覆蓋這些遠(yuǎn)程屬性源。一般來說過,啟動(dòng)命令行參數(shù)的優(yōu)先級(jí)高于遠(yuǎn)程配置,可以通過設(shè)定啟動(dòng)命令行參數(shù)的方式覆蓋遠(yuǎn)程配置。
如果想使用應(yīng)用程序的系統(tǒng)屬性或者配置文件覆蓋遠(yuǎn)程屬性,那么遠(yuǎn)程屬性源必須設(shè)置為spring.cloud.config.allowOverride=true(這個(gè)配置在本地設(shè)置不會(huì)生效)。在遠(yuǎn)程屬性源中設(shè)定上述配置后,就可以通過更為細(xì)粒度的設(shè)置來控制遠(yuǎn)程屬性是否能被重載,具體配置如下所示。
spring:
cloud:
config:
overrideNone: true #本地屬性覆蓋所有的遠(yuǎn)程屬性源
overrideSystemProperties: false#僅覆蓋遠(yuǎn)程屬性源中的系統(tǒng)屬性和環(huán)境變量
5.自定義Bootstrap配置
自定義Bootstrap配置過程與Spring Boot自動(dòng)配置運(yùn)行原理類似,具體操作是在/META-INF/spring.factories文件中添加org.springframework.cloud.bootstrap.BootstrapConfiguration配置項(xiàng)。配置項(xiàng)的值是一系列用來創(chuàng)建Context的@Configuration配置類,配置類之間以逗號(hào)分隔。這些類可以為應(yīng)用上下文提供Bean實(shí)例,配置類可以通過標(biāo)記@Order來控制Bean實(shí)例初始化序列。如下例所示,在引導(dǎo)過程中添加了一個(gè)LogAutoConfiguration的配置類,為應(yīng)用程序添加日志相關(guān)的Bean實(shí)例:
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.demo.starter.config.LogAutoConfiguration
6.自定義Bootstrap屬性源
默認(rèn)的Bootstrap外部配置屬性源是Spring Cloud Config Server,即使用配置中心加載外部屬性。但是用戶也可以通過將PropertySourceLocator類型的Bean實(shí)例添加到Bootstrap上下文(在spring.factories添加對(duì)應(yīng)的配置類)來添加額外的屬性來源。通過這種方法可以從不同的服務(wù)器或者數(shù)據(jù)庫中加載額外的屬性,如下所示:
@Configuration
public class CustomPropertySourceLocator implements PropertySourceLocator {
@Override
public PropertySource> locate(Environment environment) {
return new MapPropertySource("customProperty",
Collections.
}
}
上述代碼中傳入的Environment參數(shù)用于創(chuàng)建應(yīng)用上下文,它具有Spring Boot提供的屬性源,可以使用它們來加載特定的屬性源(例如重新設(shè)置spring.application.name)??梢栽贛ETA-INF/spring.factories文件中添加如下記錄來配置屬性源:
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
sample.custom.CustomPropertySourceLocator
上述配置令應(yīng)用程序可以使用CustomPropertySourceLocator作為其屬性源。
7. Environment變化
Config Client應(yīng)用程序會(huì)監(jiān)聽EnvironmentChangeEvent事件,當(dāng)監(jiān)聽到一個(gè)EnvironmentChangeEvent時(shí),它將持有一個(gè)被改變的鍵值對(duì)列表,應(yīng)用程序使用這些值來:
重新綁定所有的@ConfigurationProperties的Bean實(shí)例,更新本地的配置屬性。
為在logging.level.*的所有屬性設(shè)置日志的等級(jí)。
一般來講,Config Client默認(rèn)不會(huì)使用輪詢方法來監(jiān)聽Environment中的改變。在Spring Cloud中,Spring Cloud Config Server使用Spring Cloud Bus將EnvironmentChangeEvent廣播到所有的Config Client中,通知它們Environment發(fā)生變化。
EnvironmentChangeEvent是一個(gè)事件類,用于在Environment發(fā)生修改時(shí)發(fā)布事件。開發(fā)者可以通過訪問/configprops端點(diǎn)(常規(guī)的Spring Boot Actuator端點(diǎn))來驗(yàn)證這些更改是否綁定到@ConfigurationProperties的Bean實(shí)例上。例如一個(gè)DataSource的最大連接數(shù)量在運(yùn)行時(shí)被改變了(DataSource默認(rèn)由Spring Boot創(chuàng)建,屬于@ConfigurationProperties的Bean)并且動(dòng)態(tài)增加容量,可以通過查看Config Client應(yīng)用程序的/configprops端點(diǎn)來驗(yàn)證DataSource的最大連接池?cái)?shù)量是否發(fā)生變化。
8.刷新范圍
一個(gè)被標(biāo)記為@RefreshScope的Spring Bean實(shí)例在配置發(fā)生變更時(shí)可以重新進(jìn)行初始化,即動(dòng)態(tài)刷新配置,這是為了解決狀態(tài)Bean實(shí)例只能在初始化的時(shí)候才能進(jìn)行屬性注入的問題。
被@RefreshScope修飾的Bean實(shí)例是懶加載的,即當(dāng)它們被使用的時(shí)候才會(huì)進(jìn)行初始化(方法被調(diào)用的時(shí)候),想要在下次方法調(diào)用前強(qiáng)制重新初始化一個(gè)Bean實(shí)例,只需要將它的緩存失效即可。
RefreshScope是上下文中的一個(gè)Bean實(shí)例,它有一個(gè)公共方法refreshAll,該方法可以通過清除目標(biāo)緩存來刷新作用域中的所有Bean實(shí)例。RefreshScope也有一個(gè)refresh方法來按照名字刷新單個(gè)Bean。
Spring Spring Cloud 微服務(wù) Bootstrap
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。