為什麼要統一管理微服務配置?
對于傳統的單體應用,常使用配置檔案管理所有配置。例如一個Spring Boot開發的單體應用,可将配置内容放在application.yml檔案中。如果需要切換環境,可設定多個Profile,并在啟動應用時指定spring.profiles.active={profile}。然而,在微服務架構中,微服務的配置管理一般有以下需求:
- 集中管理配置:一個使用微服務架構的應用系統可能會包含成百上千個微服務,是以集中管理配置是非常有必要的;
- 不同環境不同配置:例如資料源配置在不同的環境中是不同的;
- 運作期間可動态調整:例如可根據各個微服務的負載情況,動态調整資料源連接配接池大小或熔斷門檻值,并且在調整配置時不停止微服務;
- 配置修改後可自動更新:如配置内容發生變化,微服務能夠自動更新配置;
Spring Cloud Config簡介
Spring Cloud Config為分布式系統外部化配置提供了伺服器端和用戶端的支援,它包括Config Server和Config Client兩部分。
Config Server是一個可橫向擴充、集中式的配置伺服器,它用于集中管理應用程式各個環境下的配置,預設使用Git存儲配置内容。
Config Client是Config Server的用戶端,用于操作存儲在Config Server中的配置屬性:

編寫Config Server
1:在GitHub的SpringCloudConfig倉庫建立幾個配置檔案:
config-server.properties
config-server-test.properties
config-server-prod.properties
config-server-dev.properties
内容分别是:
profile=default-1.0
profile=test-1.0
profile=prod-1.0
profile=dev-1.0
2:建立Spring Boot項目CloudConfig,添加依賴Config Server
3:啟動類
@EnableConfigServer
@SpringBootApplication
public class CloudConfigApplication {
public static void main(String[] args) {
SpringApplication.run(CloudConfigApplication.class, args);
}
}
4:配置檔案application.yml
server:
port: 8080
spring:
application:
name: configserver
cloud:
config:
server:
git:
uri: https://github.com/z1790424577/SpringCloudConfig # 配置Git倉庫的位址
username: # GitHub倉庫的使用者名
password: # GitHub倉庫的密碼
label: master #分支,預設master
Config Server的端點
可以使用Config Server的端點擷取配置檔案的内容。端點與配置檔案的映射規則如下:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
以上端點都可以映射到{application}-{profile}.properties這個配置檔案;application這裡為:config-server
按照以上規則,可使用以下URL通路到GitHub倉庫master分支的config-server-dev.properties:
http://localhost:8080/config-server/dev
http://localhost:8080/config-server-dev.properties
http://localhost:8080/config-server-dev.yml
通路:http://localhost:8080/config-server/dev
通路:http://localhost:8080/config-server-dev.properties
通路:http://localhost:8080/config-server-dev.yml
編寫Config Client
1:建立Spring Boot項目ConfigServerClient,添加依賴Config Client
2:啟動類
@SpringBootApplication
public class ConfigServerClientApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerClientApplication.class, args);
}
}
3:配置檔案application.yml
server:
port: 8081
4:配置檔案bootstrap.yml
spring:
application:
name: config-server # 對應config server所擷取的配置檔案的{application}
cloud:
config:
uri: http://localhost:8080/ //指定Config Server的位址,預設是http://localhost:8888/
profile: dev //對應Config Server所擷取的配置檔案中的{profile}
label: master //指定Git倉庫分支,對應Config Server所擷取配置檔案的{label}
以上屬性配置在bootstrap.yml,而不是application.yml中,如果配置在application.yml中,該部配置設定置就不能正常工作。例如,Config Client會直連spring.cloud.config.uri的預設值http://localhost:8888/,而非配置的http://localhost:8080/。
Spring Cloud有一個“引導上下文”的慨念,這是主應用程式的父上下文。引導上下文負責從配置伺服器加載配置屬性,以及解密外部配置檔案中的屬性。和主應用程式加載application.yml(application.properties)中的屬性不同,引導上下文加載bootstrap.yml中的屬性。配置在bootstrap.yml中的屬性具有更高的優先級,是以預設情況下它們不能被本地配置覆寫。
如需禁用引導過程,可設定spring.cloud.bootstrap.enabled=false;
5:MyController
@RestController
public class MyController {
@Value("${profile}")
private String profile;
@GetMapping("/profile")
public String hello() {
return this.profile;
}
}
6:運作測試
啟動項目CloudConfig
啟動項目ConfigServerClient
通路:http://localhost:8081/profile
說明Config Client可以正常通過Config Server獲得Git倉庫中對應環境的配置!
Config Server的Git倉庫配置詳解
1:占位符支援
Config Server的占位符支援{application}、{profile}和{label}:
spring:
application:
name: configserver
cloud:
config:
server:
git:
uri: https://github.com/z1790424577/{application} # 配置Git倉庫的位址
username: # Git倉庫的賬号
password: # Git倉庫的密碼
label: master
通路:http://localhost:8080/SpringCloudConfig-default.yml
擷取到http://localhost:8080/SpringCloudConfig下的application.properties
2:搜尋目錄
spring:
application:
name: configserver
cloud:
config:
server:
git:
uri: https://github.com/z1790424577/SpringCloudConfig # 配置Git倉庫的位址
search-paths:
- test
username: # Git倉庫的賬号
password: # Git倉庫的密碼
label: master
通路:http://localhost:8080/config-server-haha.properties
3:啟動時加載配置檔案
spring:
application:
name: configserver
cloud:
config:
server:
git:
clone-on-start: true
uri: https://github.com/z1790424577/SpringCloudConfig # 配置Git倉庫的位址
username: # Git倉庫的賬号
password: # Git倉庫的密碼
label: master
Config Server的健康狀況訓示器
spring:
application:
name: configserver
cloud:
config:
server:
git:
clone-on-start: true
uri: https://github.com/z1790424577/SpringCloudConfig # 配置Git倉庫的位址
username: # Git倉庫的賬号
password: # Git倉庫的密碼
health:
repositories:
a-foo:
label: master
name: config-server //自定義健康狀況訓示器
profiles: dev
label: master
management:
security: //關閉actuator的端點認證
enabled: false
使用/refresh端點手動重新整理配置
1:為項目ConfigServerClient添加依賴Actuator
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2:MyController
@RefreshScope //添加@RefreshScope的類會在配置更改時得到特殊的處理
@RestController
public class MyController {
@Value("${profile}")
private String profile;
@GetMapping("/profile")
public String hello() {
return this.profile;
}
}
3:運作測試
啟動項目CloudConfig
啟動項目ConfigServerClient
通路:http://localhost:8081/profile;
修改Git倉庫中config-server-dev.properties檔案内容為:profile=dev-1.0-change;
重新通路:http://localhost:8081/profile,結果不變,說明配置尚未重新整理;
發生POST請求到:http://localhost:8081/refresh;
傳回結果:“profile”,表示profile這個配置屬性已被重新整理;
再次通路:http://localhost:8081/profile;
Spring Cloud Config與Eureka配合使用
1:建立Spring Boot項目EurekaServer,添加依賴Eureka Server
2:啟動類:
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
3:配置檔案application.yml
server:
port: 8761
eureka:
client:
registerWithEureka: false #是否将自己注冊到Eureka Server,預設為True。由于目前應用就是Eureka Server,故false
fetchRegistry: false #是否從Eureka Server擷取注冊資訊,預設True。因為這是一個單節點的Eureka Server,不需要同步其他的Eureka Server節點,故false
serviceUrl:
defaultZone: http://localhost:8761/eureka/
4:項目CloudConfig添加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
5:項目CloudConfig啟動類
@EnableConfigServer
@SpringBootApplication
@EnableEurekaClient
public class CloudConfigApplication {
public static void main(String[] args) {
SpringApplication.run(CloudConfigApplication.class, args);
}
}
6:項目ConfigServerClient添加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
7:項目ConfigServerClient啟動類
@EnableEurekaClient
@SpringBootApplication
public class ConfigServerClientApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerClientApplication.class, args);
}
}
8:項目ConfigServerClient bootstrap.yml
spring:
application:
name: config-server # 對應config server所擷取的配置檔案的{application}
cloud:
config:
uri: http://localhost:8080/
profile: dev
label: master
discovery:
enabled: true # 表示使用服務發現元件中的Config Server,而不自己指定Config Server的uri,預設false
service-id: configserverclient # 指定Config Server在服務發現中的serviceId,預設是configserver
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
9:運作測試
啟動項目EurekaServer
啟動項目CloudConfig
啟動項目ConfigServerClient
Spring Cloud Config的使用者認證
上面示例中,Config Server是允許匿名通路的。為了防止配置内容的外洩,應該保護Config Server的安全;
1:項目CloudConfig添加依賴Security
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2:application.yml添加如下内容
security:
user:
name: user
password: 123456
通路:http://localhost:8080/config-server/dev
Config Client連接配接需使用者認證的Config Server
方式1:項目ConfigServerClient的bootstrap.yml
spring:
cloud:
config:
uri: http://user:[email protected]:8080/
方式2:項目ConfigServerClient的bootstrap.yml
spring:
cloud:
config:
uri: http://localhost:8080/
#username: user
#password: 123456
運作測試
啟動項目EurekaServer
啟動項目CloudConfig
啟動項目ConfigServerClient
通路:http://localhost:8081/profile
如果沒有指定的話,通路http://localhost:8081/profile會報錯!
參考書籍:Spring Cloud與Docker微服務架構實戰
以上隻是學習所做的筆記,以供日後參考!!!