(七)Spring Cloud 配置中心config
- 2020 年 4 月 10 日
- 筆記
spring cloud config是一個基於http協議的遠程配置實現方式。
通過統一的配置管理伺服器進行配置管理,客戶端通過http協議主動的拉取服務的的配置資訊,完成配置獲取。
下面我們對spring cloud config配置中心進行搭建
主要有以下模組
eureka-server 服務註冊中心
eureka-config config配置中心
eureka-config-resp1 git遠程倉庫,用於存儲客戶端的配置文件
eureka-client1 客戶端1,它的配置從config配置中心讀取
eureka-client2 客戶端2,它的配置從config配置中心讀取
1. eureka-server註冊中心
1.1 eureka-server pom 文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.devin</groupId> <artifactId>eureka-server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eureka-server</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
1.2 安全配置
package com.devin.eurekaserver.config; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { //關閉csrf super.configure(http); //開啟認證 http.csrf().disable(); } }
1.3 啟動類
package com.devin.eurekaserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer @SpringBootApplication public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
1.4 eureka-server application.yml 配置
啟動埠為 7001
server: port: 7001 #啟動埠 spring: #應用名稱 application: name: eureka-server #安全配置 security: basic: enabled: true user: name: dev password: 123456 #eureka配置 eureka: server: #設置掃描失效服務的間隔時間 eviction-interval-timer-in-ms: 20000 enable-self-preservation: true instance: hostname: localhost leaseRenewalIntervalInSeconds: 10 health-check-url-path: /actuator/health client: register-with-eureka: false #false:不作為一個客戶端註冊到註冊中心 fetch-registry: false #為true時,可以啟動,但報異常:Cannot execute request on any known server service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # health endpoint是否必須顯示全部細節。默認情況下, /actuator/health 是公開的,並且不顯示細節。 # 設置actuator開關 management: security: enabled: false endpoints: web: exposure: include: "*" endpoint: health: show-details: ALWAYS
2. 配置中心config
2.1 pom.xml 完整配置
主要添加了 config-server(配置中心) ,mq ,actuator(spring bus配置中心刷新), eureka-client 的依賴
ps: 搭建時在使用idea自帶的版本時,在用到配置刷新時會報mq的異常,所以這裡更改了spirngboot和spirng cloud的版本,具體看配置文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.devin</groupId> <artifactId>eureka-config</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eureka-config</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <!-- springcloud-bus依賴實現配置自動更新,rabbitmq --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.2 啟動類
@EnableConfigServer 對config配置中心的支援
@EnableEurekaClient 將配置中心也作為一個eureka-client在註冊中心進行註冊
package com.devin.eurekaconfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @EnableConfigServer @EnableEurekaClient @SpringBootApplication public class EurekaConfigApplication { public static void main(String[] args) { SpringApplication.run(EurekaConfigApplication.class, args); } }
2.3 config配置中心的配置文件
我們這裡採用了多profile的配置,分別對應dev和test環境
2.3.1 bootstrap.yml
主要配置了連接git倉庫的地址,這裡我們查找的路徑按項目進行劃分,使用了{application}佔位,當客戶端的服務名為eureka-clent時,將在git地址的eureka-client文件夾下進行配置查找並使用
server: port: 7009 spring: profiles: active: dev #應用名稱 application: name: eureka-config cloud: config: server: git: uri: https://github.com/devinzhang0209/eureka-config-resp1.git # username: devinzhang0209 # password: yourgithubpassword search-paths: /{application} label: master # health endpoint是否必須顯示全部細節。默認情況下, /actuator/health 是公開的,並且不顯示細節。 management: endpoints: web: exposure: include: "*" endpoint: health: show-details: ALWAYS
2.3.2 測試環境功能 bootstrap-dev.yml
主要配置了向eureka-server 進行註冊,以及mq的配置用於配置的刷新
#配置config服務的帳號密碼 spring: security: user: name: dev-config password: 123456 rabbitmq: host: localhost port: 5672 username: guest password: guest #註冊中心配置 eureka: auth: user: dev password: 123456 client: service-url: defaultZone: http://${eureka.auth.user}:${eureka.auth.password}@localhost:7001/eureka/ instance: #使用IP進行註冊 prefer-ip-address: true #配置實例的註冊ID instance-id: ${spring.cloud.client.ip-address}:${server.port} #心跳時間,即服務續約間隔時間(預設為30s) lease-renewal-interval-in-seconds: 5 #發獃時間,即服務續約到期時間(預設為90s) lease-expiration-duration-in-seconds: 10 health-check-url-path: /actuator/health
2.3.3 測試環境功能 bootstrap-test.yml
這裡的配置和dev環境一樣,主要是為了測試test環境去讀取git倉庫中test對應的配置資訊
#配置config服務的帳號密碼 spring: security: user: name: dev-config-test password: test123456 #註冊中心配置 eureka: auth: user: dev-test password: test123456 client: service-url: defaultZone: http://${eureka.auth.user}:${eureka.auth.password}@192.168.0.12:7001/eureka/ instance: #使用IP進行註冊 prefer-ip-address: true #配置實例的註冊ID instance-id: ${spring.cloud.client.ip-address}:${server.port} #心跳時間,即服務續約間隔時間(預設為30s) lease-renewal-interval-in-seconds: 5 #發獃時間,即服務續約到期時間(預設為90s) lease-expiration-duration-in-seconds: 10 health-check-url-path: /actuator/health
3. git倉庫 eureka-config-resp1
git倉庫中主要存儲了不同eureka-client客戶端的不同環境對應的配置文件, 結構如下:
git的地址是 https://github.com/devinzhang0209/eureka-config-resp1.git 這裡我設置的是一個公共的倉庫
下面我們展示eureka-clien的配置
3.1 application.yml
spring: application: name: eureka-client
3.2 application-dev.yml
server: port: 7003 msg: this msg is response by port 7003
3.3 application-test.yml
server: port: 7004 msg: this msg is response by port 7004
4. eureka-client
4.1 pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.devin</groupId> <artifactId>eureka-client</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eureka-client</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <!--<spring-cloud.version>Hoxton.SR3</spring-cloud.version>--> <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> <version>1.4.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.1.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
4.2 啟動類
package com.devin.eurekaclient; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @EnableEurekaClient @SpringBootApplication public class EurekaClientApplication { public static void main(String[] args) { SpringApplication.run(EurekaClientApplication.class, args); } }
4.3 controller 測試類
其中 @RefreshScope,用於後續spring config bus刷新配置文件
package com.devin.eurekaclient.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author Devin Zhang * @className HelloController * @description TODO * @date 2020/4/2 9:50 */ @RefreshScope @RestController public class HelloController { @Value("${server.port}") private Integer port; @Value("${msg}") private String msg; @GetMapping("/getMSG") public String getMsg() { return msg + " ,response by port:" + port; } }
4.4 eureka-client的本地配置文件
4.4.1 bootstrap.yml
spring: profiles: active: dev #應用名稱 application: name: eureka-client # health endpoint是否必須顯示全部細節。默認情況下, /actuator/health 是公開的,並且不顯示細節。 management: endpoints: web: exposure: include: "*" endpoint: health: show-details: ALWAYS
4.4.2 bootstrap-dev.yml
#註冊中心配置 eureka: auth: user: dev password: 123456 client: service-url: defaultZone: http://${eureka.auth.user}:${eureka.auth.password}@localhost:7001/eureka/ instance: #使用IP進行註冊 prefer-ip-address: true #配置實例的註冊ID instance-id: ${spring.cloud.client.ip-address}:${server.port} #心跳時間,即服務續約間隔時間(預設為30s) lease-renewal-interval-in-seconds: 5 #發獃時間,即服務續約到期時間(預設為90s) lease-expiration-duration-in-seconds: 10 health-check-url-path: /actuator/health spring: cloud: #config服務配置 config: username: dev-config password: 123456 fail-fast: false #重試間隔時間 retry: initial-interval: 3000 #從註冊中心獲取配置服務,以及配置服務名稱 discovery: enabled: true service-id: eureka-config rabbitmq: host: localhost port: 5672 username: guest password: guest
4.4.3 bootstrap-test.yml
#註冊中心配置 eureka: auth: user: dev password: 123456 client: service-url: defaultZone: http://${eureka.auth.user}:${eureka.auth.password}@localhost:7001/eureka/ instance: #使用IP進行註冊 prefer-ip-address: true #配置實例的註冊ID instance-id: ${spring.cloud.client.ip-address}:${server.port} #心跳時間,即服務續約間隔時間(預設為30s) lease-renewal-interval-in-seconds: 5 #發獃時間,即服務續約到期時間(預設為90s) lease-expiration-duration-in-seconds: 10 health-check-url-path: /actuator/health spring: cloud: #config服務配置 config: username: dev-config password: 123456 fail-fast: false #重試間隔時間 retry: initial-interval: 3000 #從註冊中心獲取配置服務,以及配置服務名稱 discovery: enabled: true service-id: eureka-config rabbitmq: host: localhost port: 5672 username: guest password: guest
5. eureka-client2
eureka-client2 和 eureka-client 完全一樣只是實例的名稱不一樣,方便我們驗證多個client在配置中心註冊 ,此處程式碼就不在展示
7. 消息隊列RabbitMQ
配置中心刷新時需要用到消息隊列
7.1 安裝RabbitMQ
本文直接在windows上驗證,需要安裝如下軟體:
Erlang otp_win64_22.3.exe
RabbitMQ rabbitmq-server-3.8.3.exe
7.2 配置環境變數
安裝完成後需要如下環境變數
ERLANG_HOME=D:Program Fileserl10.7
RABBITQM_SERVER=D:Program FilesRabbitMQ Serverrabbitmq_server-3.8.3
path=%Path%;%ERLANG_HOME%bin;%RABBITQM_SERVER%sbin;
7.3 啟動mq的服務
7.4 開啟RabbitMQ管理服務端
rabbitmq-plugins enable rabbitmq_management
開啟後訪問的默認地址: http://localhost:15672/ 默認帳號密碼 guest/guest
8 驗證配置中心
分別啟動
eureka-server
eureka-config
eureka-client
eureka-client2
啟動 eureka-client 和eureka-clent2 從啟動日誌中可以看到程式已經去配置中心7009讀取配置並從github上讀取了配置文件並使用
分別訪問
可以看到euerka-client 和 eureka-client2 已經讀取了啟動埠,Controller也通過@Value讀取了git中的配置資訊
9. Spring Cloud Bus 刷新配置
刷新配置我們需要注意如下幾點
1. 在使用刷新配置時,需要去掉eureka-config 和eueka-client 中的安全驗證 ,直接在pom文件中去掉如下依賴即可
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <scope>compile</scope> </dependency>
2. 在eureka-config 和eueka-client 的yml配置文件中添加RabbitMQ的配置
#配置config服務的帳號密碼 spring: security: user: name: dev-config password: 123456 rabbitmq: host: localhost port: 5672 username: guest password: guest
3. 在客戶端所有用到讀取配置文件的類上加上 @RefreshScope
4. 刷新配置
刷新配置可以訪問eureka-config也可以訪問任何一個eureka-client的服務進行刷新,如下刷新請求只能通過post請求去調用
通過eureka-config 去刷新 http://localhost:7009/actuator/bus-refresh
通過eureka-client 去刷新 http://localhost:7003/actuator/bus-refresh
刷新後我們再後台log中可以看到,客戶端已經去github上重新讀取了最新的配置
再次訪問客戶端,可以看到客戶端已經讀取到了最新的配置
至此,spring cloud config配置中心搭建完畢