SpringCloud(九)Spring Cloud Config 分布式配置中心
分布式配置中心應用場景
往往,我們使用配置檔案管理一些配置資訊,比如application.properties
單體應用架構,配置資訊的管理、維護并不會顯得特别麻煩,手動操作就可以,因為就一個工程;
微服務架構,因為我們的分布式叢集環境中可能有很多個微服務,我們不可能一個一個去修改配置然後重新開機生效,在一定場景下我們還需要在運作期間動态調整配置資訊,比如:根據各個微服務的負載情況,動态調整資料源連接配接池大小,我們希望配置内容發生變化的時候,微服務可以自動更新。
場景總結如下:
1)集中配置管理,一個微服務架構中可能有成百上千個微服務,是以集中配置管理是很重要的(一次修改、到處生效)
2)不同環境不同配置,比如資料源配置在不同環境(開發dev,測試test,生産prod)中是不同的
3)運作期間可動态調整。例如,可根據各個微服務的負載情況,動态調整資料源連接配接池大小等配置修改後可自動更新
4)如配置内容發生變化,微服務可以自動更新配置
那麼,我們就需要對配置檔案進行集中式管理,這也是分布式配置中心的作用。
Spring Cloud Config
Config簡介
Spring Cloud Config是一個分布式配置管理方案,包含了 Server端和 Client端兩個部分。
- Server 端:提供配置檔案的存儲、以接口的形式将配置檔案的内容提供出去,通過使用@EnableConfigServer注解在 Spring boot 應用中非常簡單的嵌入
- Client 端:通過接口擷取配置資料并初始化自己的應用
Config分布式配置應用
說明:Config Server是集中式的配置服務,用于集中管理應用程式各個環境下的配置。 預設使用Git存儲配置檔案内容,也可以SVN。
比如,我們要對“靜态化微服務或者商品微服務”的application.yml進行管理(區分開發環境(dev)、測試環境(test)、生産環境(prod))
1)登入GitHub,建立項目szx-config
2)上傳yml配置檔案,命名規則如下:
{application}-{profile}.yml 或者 {application}-{profile}.properties
其中,application為應用名稱,profile指的是環境(用于區分開發環境,測試環境、生産環境等)
示例:szx-service-page-dev.yml、szx-service-page-test.yml、szx-service-page-prod.yml
3)建構Config Server統一配置中心
建立SpringBoot工程,引入依賴坐标(需要注冊自己到Eureka)
<dependencies>
<!--eureka client 用戶端依賴引入-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--config配置中心服務端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
配置啟動類,使用注解@EnableConfigServer開啟配置中心伺服器功能
@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer //開啟配置伺服器功能
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class,args);
}
}
application.yml配置
#配置端口
server:
port: 9400
#配置Eurake,将網關注冊到Eureka
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:9202/eureka/,http://127.0.0.1:9201/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}:@project.version@
#配置config
spring:
application:
name: szx-service-config
#配置GitHub
cloud:
config:
server:
#配置git服務位址
git:
uri: https://gitee.com/lemonStar/szx-config.git #配置GIT位址
username: #GIT使用者名
password: #GIT密碼
search-paths:
- szx-config
#指定分支
label: master
測試:http://127.0.0.1:9400/master/application_dev.yml
- master:分支名稱
- application-dev.yml:檔案名稱
4)建構Client用戶端(在已有頁面靜态化微服務基礎上)
案例實作:在szx-service-page微服務中動态擷取config server的配置資訊
已有工程中添加依賴坐标
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
application.properties修改為bootstrap.properties配置檔案
bootstrap.yml是系統級别的,優先級比application.yml高,應用啟動時會檢查這個配置檔案,在這個配置檔案中指定配置中心的服務位址,會自動拉取所有應用配置并且啟用。
(主要是把與統一配置中心連接配接的配置資訊放到bootstrap.yml)
注意:需要統一讀取的配置資訊,從配置中心擷取
bootstrap.properties(部分)
#配置springcloud config(分布式配置中心的配置)資訊
spring.cloud.config.name=application
spring.cloud.config.profile=dev
#分支名稱
spring.cloud.config.label=master
#config server位址
spring.cloud.config.uri=http://127.0.0.1:9400
@RestController
@RequestMapping("/config")
public class ConfigClientController {
@Value("${mysql.user}")
private String user;
@Value("${person.name}")
private String name;
@GetMapping("/getConfigInfo")
public String getConfigInfo(){
return user + name;
}
}
Config配置手動重新整理
不用重新開機微服務,隻需要手動的做一些其他的操作(通路一個位址/refresh)重新整理,之後再通路即可
此時,用戶端取到了配置中心的值,但當我們修改GitHub上面的值時,服務端(Config Server)能實時擷取最新的值,但用戶端(Config Client)讀的是緩存,無法實時擷取最新值。Spring Cloud已 經為我們解決了這個問題,那就是用戶端使用post去觸發refresh,擷取最新資料。
1)Client用戶端添加依賴springboot-starter-actuator(已添加)
2)Client用戶端bootstrap.yml中添加配置(暴露通信端點)
#springboot中暴露健康檢查等斷點接口
management.endpoints.web.exposure.include=*
#或者
management.endpoints.web.exposure.include=refresh
3)Client用戶端使用到配置資訊的類上添加@RefreshScope
@RestController
@RequestMapping("/config")
@RefreshScope //手動重新整理
public class ConfigClientController {
@Value("${mysql.user}")
private String user;
@Value("${person.name}")
private String name;
@GetMapping("/getConfigInfo")
public String getConfigInfo(){
return user + name;
}
}
4)手動向Client用戶端發起POST請求,http://localhost:9100/actuator/refresh,重新整理配置資訊
注意:手動重新整理方式避免了服務重新開機
思考:可否使用廣播機制,一次通知,處處生效,友善大範圍配置自動重新整理?
Config配置自動更新
實作一次通知,處處生效
在微服務架構中,我們可以結合消息總線(Bus)實作分布式配置的自動更新(Spring Cloud Config + Spring Cloud Bus)
消息總線Bus
所謂消息總線Bus,即我們經常會使用MQ消息代理建構一個共用的Topic,通過這個Topic連接配接各個微服務執行個體,MQ廣播的消息會被所有在注冊中心的微服務執行個體監聽和消費。換言之就是通過一個主題連接配接各個微服務,打通脈絡。
Spring Cloud Bus(基于MQ的,支援RabbitMq/Kafka) 是Spring Cloud中的消息總線方案,Spring Cloud Config + Spring Cloud Bus 結合可以實作配置資訊的自動更新。
Spring Cloud Config + Spring Cloud Bus 實作自動重新整理
MQ消息代理,我們還選擇使用RabbitMQ,ConfigServer和ConfigClient都添加都消息總線的支援以及與RabbitMq的連接配接資訊
1)Config Server服務端和用戶端添加消息總線支援
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
2)Config Server和用戶端添加配置
spring:
rabbitmq:
host: IP
port: 5672
username: guest
password: guest
3)Config Server微服務暴露端口
#springboot中暴露健康檢查等斷點接口
management.endpoints.web.exposure.include=*
#或者
management.endpoints.web.exposure.include=bus-refresh
4)重新開機各個服務,更改配置之後,向配置中心服務端發送post請求,各個用戶端配置即可自動重新整理 http://127.0.0.1:9400/actuator/bus-refresh
5)Config Client測試 http://localhost:9100/config/remote
在廣播模式下實作了一次請求,處處更新,如果我隻想定向更新呢?
在發起重新整理請求的時候 http://localhost:9006/actuator/bus-refresh/lagou-service-page:9100
即為最後面跟上要定向重新整理的執行個體的 **服務名:端口号 **即可