高可用配置
當要將配置中心部署到生產環(huán)境時唬格,與服務注冊一樣,需要時高可用的應用。spring cloud config實現(xiàn)服務端的高可用材蹬。spring cloud config實現(xiàn)服務端的高可用非常簡單紫岩,主要有以下兩種方式:
- 傳統(tǒng)方式:不需要為這些服務端做任何額外的配置规惰,遵循一個規(guī)則,將所有的config server都指向同一個git倉庫泉蝌,這樣所有的配置內容就通過統(tǒng)一的共享文件系統(tǒng)來維護歇万。而客戶端在指定config server位置時,只需要配置config server上層的負載均衡設置地址即可梨与。(此時要借助nginx等服務了)
- 服務模式: 將
config server
作為一個普通的微服務應用堕花,納入到eureka
的服務治理體系中。這樣我們的微服務應用就可以通過配置中心的服務名來獲取配置信息粥鞋,這種方式比起傳統(tǒng)的實現(xiàn)模式來說更加有利于維護缘挽,因為對于服務端的負載均衡配置和客戶端的配置中心制定都通過服務治理機制一并解決了,即實現(xiàn)了高可用,也實現(xiàn)了自維護壕曼。
客戶端詳解
uri指定配置中心(Config First Bootstrap)
spring cloud config
的客戶端在啟動的時候苏研,默認會從工程的classpath
中加載配置信息并啟動應用。只有當我們配置spring.cloud.config.uri
的時候腮郊,客戶端應用才會嘗試連接spring cloud config
的服務端來獲取遠程配置信息并初始化spring環(huán)境配置摹蘑。同時,我們必須將該參數配置在bootstrap.yml
轧飞,環(huán)境變量或是其他優(yōu)先級高于應用jar包內的配置信息中衅鹿,才能正確加載到遠程配置。若不指定spring.cloud.uri
參數的話过咬,spring cloud config
的客戶端會默認嘗試連接http://localhost:8888
大渤。
spring:
application:
name: zhihaomiao
cloud:
config:
uri: http://localhost:9090/
profile: pro
label: config-label-test
服務化配置中心(Discovery First Bootstrap)
config server
注冊到服務中心,并被其他應用所發(fā)現(xiàn)實現(xiàn)配置信息獲取掸绞。我們把config server
看作一個微服務泵三。
對快速入門進行改造:
服務端配置:
- 在config-server的pom.xml總增加eureka依賴,如下:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
- 在application.yml中配置注冊eureka的相關參數:
security:
basic:
enabled: true
user:
name: user
password: root123456
spring:
application:
name: config-server-git
cloud:
config:
server:
git:
uri: http://git.oschina.net/zhihaomiao/{application}-config
username: zhihao.miao
password: 13579qwertyu
server:
port: 9090
encrypt:
key: zhihao.miao
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
prefer-ip-address: true
- 在應用主類中衔掸,新增
@EnableDiscoveryClient
注解烫幕,用來將config-server
注冊到配置中心
@EnableDiscoveryClient
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class,args);
}
}
- 啟動
eureka
服務,可以看到config-server
在eureka
控制面板的信息敞映。
客戶端配置:
- 在
order-service
的pom中新增了eureka
依賴较曼,以實現(xiàn)客戶端發(fā)現(xiàn)config-server
服務,具體依賴如下:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
- 在bootstrap.yml中驱显,按如下配置:
spring:
application:
name: order-service
cloud:
config:
discovery:
enabled: true
service-id: config-server-git
username: user
password: root123456
profile: pro
label: master
server:
port: 6060
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
prefer-ip-address: true
其中诗芜,通過eureka.client.service-url.defaultZone
參數指定服務注冊中心,用于服務的注冊與發(fā)現(xiàn)埃疫,將spring.cloud.config.discovery.enabled
參數設置為true
伏恐,開啟通過服務來訪問config server
的功能;spring.cloud.config. discovery.service-id
參數來指定config server
注冊的服務名栓霜。這里的spring.application.name
和spring.cloud.config.profile
和之前一樣翠桦,定位git中的資源。
- 應用主類上加上@EnableDiscoveryClient注解胳蛮,用來發(fā)現(xiàn)config-server-git的服務销凑,利用其發(fā)現(xiàn)服務進行加載應用配置:
@EnableDiscoveryClient
@SpringBootApplication
public class ConfigClientApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientApplication.class,args);
}
}
官網中還有這一段:
The discovery client implementations all support some kind of metadata map (e.g. for Eureka we have eureka.instance.metadataMap). Some additional properties of the Config Server may need to be configured in its service registration metadata so that clients can connect correctly. If the Config Server is secured with HTTP Basic you can configure the credentials as "username" and "password". And if the Config Server has a context path you can set "configPath". Example, for a Config Server that is a Eureka client:
服務發(fā)現(xiàn)客戶端實現(xiàn)都支持一些元數據映射(例如,對于Eureka仅炊,我們有eureka.instance.metadataMap
配置)斗幼。 可能需要在其服務注冊元數據中配置Config Server的一些其他屬性,以便客戶端可以正確連接抚垄。 如果使用HTTP Basic安全配置服務器蜕窿,則可以將憑據配置為“用戶名”和“密碼”谋逻。 并且如果配置服務器具有上下文路徑,您可以設置“configPath”桐经。 例如毁兆,對于作為Eureka客戶端的配置服務器:
bootstrap.yml
eureka:
instance:
...
metadataMap:
user: osufhalskjrtl
password: lviuhlszvaorhvlo5847
configPath: /config
在我的理解就是服務注冊的客戶端與服務注冊服務端進行數據交互驗證的時候可以使用這個屬性
參考資料
Discovery First Bootstrap
失敗快速響應與重試
spring cloud config
的客戶端會預先加載很多其他信息,然后再開始連接config server
進行屬性的注入阴挣,當我們構建的應用比較復雜的時候气堕,可能在連接config server
之前花費太多的啟動時間,而在一些特殊的場景下畔咧,我們希望可以快速知道當前應用是否能順利地從config server
獲取到配置信息茎芭,這對在初期構建調試環(huán)境時,可以減少很多等待啟動的時間誓沸。要實現(xiàn)客戶端優(yōu)先判斷config server
獲取是否正常骗爆,并快速響應失敗內容,只需在bootstrap.yml
中配置參數spring.cloud.config.failFast=true
即可蔽介。
測試一下,在沒有該參數前煮寡,不啟動config server
虹蓄,直接啟動客戶端應用,可以獲得下面的報錯信息幸撕,同時薇组,在報錯之前,可以看到客戶端應用已經加載了很多內容坐儿,比如controller的請求律胀,只有在屬性注入的時候報錯了,
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configClientController': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.username' in value "${spring.datasource.username}"
加上spring.cloud.config.failFast=true
參數之后貌矿,再啟動客戶端應用炭菌,可以獲得下面的報錯信息,并且前置的加載內容少了很多逛漫,這樣通過該參數有效避免了當config server
配置有誤時黑低,不需要多等待前置的一些加載時間,實現(xiàn)快速失敗信息酌毡。
java.lang.IllegalStateException: Could not locate PropertySource and the fail fast property is set, failing
at org.springframework.cloud.config.client.ConfigServicePropertySourceLocator.locate(ConfigServicePropertySourceLocator.java:130) ~[spring-cloud-config-client-1.2.3.RELEASE.jar:1.2.3.RELEASE]
at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.initialize(PropertySourceBootstrapConfiguration.java:89) ~[spring-cloud-context-1.1.9.RELEASE.jar:1.1.9.RELEASE]
at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:636) [spring-boot-1.4.5.RELEASE.jar:1.4.5.RELEASE]
at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:350) [spring-boot-1.4.5.RELEASE.jar:1.4.5.RELEASE]
上面克握,我們演示了當config server宕機或是客戶端配置不正確導致連接不到而啟動失敗的情況,快速響應的配置可以發(fā)揮比較好的效果枷踏。但是菩暗,若只是因為網絡波動等其他間歇性原因導致的問題,直接啟動失敗似乎代價有點高旭蠕。所以停团,config客戶端還提供了重試的功能旷坦,在開啟重試功能前,先確保已經配置了spring.cloud.config.failFast=true
客蹋,在進行下面的操作:
- 在
pom.xml中增加spring.retry
和spring-boot-starter-aop
依賴:
<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 server
失敗之后番电,繼續(xù)嘗試,直到第6次失敗后辆琅,才返回錯誤信息漱办。通過這樣的重試機制,可以避免一些間歇性問題引起的失敗導致客戶端應用無法啟動的情況婉烟。
2017-08-18 18:29:44.142 INFO 55961 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2017-08-18 18:29:45.211 INFO 55961 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2017-08-18 18:29:46.345 INFO 55961 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2017-08-18 18:29:47.578 INFO 55961 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2017-08-18 18:29:48.923 INFO 55961 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2017-08-18 18:29:50.399 INFO 55961 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at: http://localhost:8888
2017-08-18 18:29:50.405 WARN 55961 --- [ main] o.s.boot.SpringApplication : Error handling failed (ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1d61c6dc: startup date [Thu Jan 01 08:00:00 CST 1970]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@3af9c5b7)
2017-08-18 18:29:50.413 ERROR 55961 --- [ main] o.s.boot.SpringApplication : Application startup failed
如果是配置具體的uri的話那么就會重試6次的uri配置娩井,如果是配置的eureka
注冊的話,就會發(fā)6次http://localhost:8888
失敗似袁。
若對默認的最大重試次數和重試間隔等設置不滿意洞辣,還可以通過下面的參數進行調整:
-
spring.cloud.config.retry.multiplier
:初始重試間隔時間(單位為毫秒),默認是1000毫秒昙衅。 -
spring.cloud.config.retry.initial-interval
:下一個間隔的乘數扬霜,默認是1.1,所以當最初間隔式1000毫秒時而涉,下一次失敗后的間隔為1100毫秒著瓶。 -
spring.cloud.config.retry.max-interval
:最大間隔時間,默認是2000毫秒啼县。 -
spring.cloud.config.retry.max-attempts
:最大重試次數材原,默認為6次。
參考資料
Config Client Fail Fast
Config Client Retry
獲取遠程配置
在快速入門中季眷,我們對 {application}
, {profile}
, {label}
這些參數已經有了一定的了解余蟹。在git倉庫中缸兔,一個形如 {application}-{profile}.properties
或是 {application}-{profile}.yml
的配置文件米诉,通過uri請求和客戶端配置訪問對應可以總結如下:
- 通過向config-server發(fā)送get請求以直接的方式獲取,可用下面的鏈接形式:
不帶{label}分支信息脯宿,默認訪問master分支话告,可使用
- /{application}-{profile}.yml
- /{application}-{profile}.properties
帶{label}分支信息兼搏,可使用:
- /{label}/{application}-{profile}.yml
- /{application}/{profile}[/{label}]
- /{label}/{application}-{profile}.properties
- 通過客戶端配置方式加載的內容如下所示
- spring.application.name: 對應配置文件中的{application}內容
- spring.application.profile: 對應配置文件中{profile}內容
- spring.application.config.label: 對應分支內容,如不配置沙郭,默認為master
參考資料
Locating Remote Configuration Resources
本博客代碼
代碼地址
配置倉庫
user服務配置倉庫
order服務配置倉庫