【前面的話】本文的某些知識依賴個人微服務系列文章,若是沒有看過能夠先移步去看一下。在前面的應用當中,咱們全部的配置都是寫在yaml配置文件當中的,這樣就會形成幾個問題:安全、統一管理等等。而SpringCloud也是考慮到這一點,給出的方案就是Spring Cloud Config。java
Spring Cloud Config是Spring Cloud團隊建立的一個全新項目,用來爲分佈式系統中的基礎設施和微服務應用提供集中化的外部配置支持,它分爲服務端與客戶端兩個部分。其中服務端也稱爲分佈式配置中心,它是一個獨立的微服務應用,用來鏈接配置倉庫併爲客戶端提供獲取配置信息、加密/解密信息等訪問接口;而客戶端則是微服務架構中的各個微服務應用或基礎設施,它們經過指定的配置中心來管理應用資源與業務相關的配置內容,並在啓動的時候從配置中心獲取和加載配置信息。Spring Cloud Config實現了對服務端和客戶端中環境變量和屬性配置的抽象映射,因此它除了適用於Spring構建的應用程序以外,也能夠在任何其餘語言運行的應用程序中使用。因爲Spring Cloud Config實現的配置中心默認採用Git來存儲配置信息,因此使用Spring Cloud Config構建的配置服務器,自然就支持對微服務應用配置信息的版本管理,而且能夠經過Git客戶端工具來方便的管理和訪問配置內容。固然它也提供了對其餘存儲方式的支持,好比:SVN倉庫、本地化文件系統。git
<parent> <artifactId>lovincloud</artifactId> <groupId>com.eelve.lovincloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>lovin-config-server</artifactId> <packaging>jar</packaging> <name>lovinconfigserver</name> <version>0.0.1</version> <description>配置服務端</description> <dependencies> <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-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-client</artifactId> <version>2.1.6</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
server: port: 8886 # 服務端口號 spring: application: name: lovinconfigserver # 服務名稱 security: basic: enabled: true user: name: lovin password: ${REGISTRY_SERVER_PASSWORD:lovin} cloud: config: server: git: uri: https://github.com/lovinstudio/lovincloud search-paths: lovin-config-repo label: master eureka: client: serviceUrl: defaultZone: http://lovin:lovin@localhost:8881/eureka/ # 註冊到的eureka服務地址
spring: cloud: config: server: git: uri: https://github.com/lovinstudio/lovincloud search-paths: lovin-config-repo username: #若是是私人倉庫,還須要配置用戶名,公共倉庫能夠省略 password: #若是是私人倉庫,還須要配置密碼,公共倉庫能夠省略 label: master
spring: cloud: config: server: svn: uri: http://192.168.0.6/svn/repo/config-repo username: username password: password default-label: trunk profiles: active: subversion #這裏須要顯式聲明爲subversion
同時還須要引入相應的配置:github
<!--SVN--> <dependency> <groupId>org.tmatesoft.svnkit</groupId> <artifactId>svnkit</artifactId> </dependency>
spring: cloud: config: server: native: searchLocations: file:D:\\config #classpath:/config profiles: active: native #native
package com.eelve.lovin.config; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; /** * @ClassName WebSecurityConfig * @Description TDO * @Author zhao.zhilue * @Date 2019/8/18 13:52 * @Version 1.0 **/ @Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().permitAll() .and().csrf().disable(); } }
package com.eelve.lovin; 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; /** * @ClassName LovinEurekaClientApplication * @Description TDO * @Author zhao.zhilue * @Date 2019/8/15 16:37 * @Version 1.0 **/ @SpringBootApplication @EnableEurekaClient @EnableConfigServer public class LovinConfigServerApplication { public static void main(String[] args) { SpringApplication.run(LovinConfigServerApplication.class,args); } }
{"name":"lovin-config","profiles":["dev"],"label":null,"version":"f0aeca26887490e3bcb8be317d4dfb378313a76f","state":null,"propertySources":[{"name":"https://github.com/lovinstudio/lovincloud/lovin-config-repo/lovin-config-dev.properties","source":{"lovin.token":"lovin"}}]}
這時咱們經過瀏覽器、POSTMAN或CURL等工具直接來訪問到咱們的配置內容了。訪問配置信息的URL與配置文件的映射關係以下:web
/{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties
上面的url會映射{application}-{profile}.properties對應的配置文件,其中{label}對應Git上不一樣的分支,默認爲master。咱們能夠嘗試構造不一樣的url來訪問不一樣的配置內容,好比,要訪問master分支,config-client應用的dev環境,就能夠訪問這個url:http://chirius:8806/lovin-config/dev,並得到以下返回:
這裏有一點疑問,我經過http://localhost:8886/lovin-config/dev/去訪問是一直不成功的,可是在換成其餘github上面別人的配置倉庫又是能夠直接訪問的spring
2019-08-19 12:55:54.686 INFO 9256 --- [nio-8886-exec-4] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/C:/Users/Chirius/AppData/Local/Temp/config-repo-8280352825025657146/lovin-config-repo/lovin-config-dev.properties 2019-08-19 12:55:57.560 INFO 9256 --- [nio-8886-exec-2] o.s.cloud.commons.util.InetUtils : Cannot determine local hostname 2019-08-19 12:55:57.576 INFO 9256 --- [nio-8886-exec-2] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/C:/Users/Chirius/AppData/Local/Temp/config-repo-8280352825025657146/lovin-config-repo/lovin-config-dev.properties 2019-08-19 12:56:00.544 INFO 9256 --- [nio-8886-exec-1] o.s.cloud.commons.util.InetUtils : Cannot determine local hostname 2019-08-19 12:56:00.559 INFO 9256 --- [nio-8886-exec-1] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/C:/Users/Chirius/AppData/Local/Temp/config-repo-8280352825025657146/lovin-config-repo/lovin-config-dev.properties 2019-08-19 12:56:07.136 INFO 9256 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration 2019-08-19 13:01:07.140 INFO 9256 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration 2019-08-19 13:06:07.142 INFO 9256 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration
ps:經過日誌咱們能夠看到配置文件是被保存在咱們本地的,固然咱們也就能夠經過配置,修改保存的路徑,具體配置爲:basedirbootstrap
新建一個config的服務端子工程lovin-config-client,用於後面的操做。下面是主要的pom依賴:瀏覽器
<parent> <artifactId>lovincloud</artifactId> <groupId>com.eelve.lovincloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>lovin-config-client</artifactId> <packaging>jar</packaging> <name>lovinconfigclient</name> <version>0.0.1</version> <description>配置消費端</description> <dependencies> <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-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-client</artifactId> <version>2.1.6</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> <version>2.1.3.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
ps:在這裏爲了監控配置變化咱們須要添加spring-boot-starter-actuator的依賴安全
spring: cloud: config: name: lovin-config profile: dev uri: http://localhost:8886/ label: master eureka: client: serviceUrl: defaultZone: http://lovin:lovin@localhost:8881/eureka/ # 注意在高可用的時候須要見註冊中心配置移到該文件中,在application.yml中見會讀取不到配置
server: port: 8807 # 服務端口號 spring: application: name: lovinconfigclient # 服務名稱 security: basic: enabled: true user: name: lovin password: ${REGISTRY_SERVER_PASSWORD:lovin}
package com.eelve.lovin.config; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; /** * @ClassName WebSecurityConfig * @Description TDO * @Author zhao.zhilue * @Date 2019/8/20 16:59 * @Version 1.0 **/ @Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().permitAll() .and().csrf().disable(); } }
package com.eelve.lovin; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * @ClassName LovinEurekaClientApplication * @Description TDO * @Author zhao.zhilue * @Date 2019/8/15 16:37 * @Version 1.0 **/ @SpringBootApplication @EnableEurekaClient public class LovinConfigClientApplication { public static void main(String[] args) { SpringApplication.run(LovinConfigClientApplication.class,args); } }
package com.eelve.lovin.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @ClassName ConfigController * @Description TDO * @Author zhao.zhilue * @Date 2019/8/20 17:17 * @Version 1.0 **/ @RestController @RefreshScope // 使用該註解的類,會在接到SpringCloud配置中心配置刷新的時候,自動將新的配置更新到該類對應的字段中。 public class ConfigController { @Value("${lovin.token}") private String token; @RequestMapping("/token") public String getToken() { return this.token; } }
PS:其中RefreshScope註解是爲了刷新配置來添加的,這樣讓配置倉庫中的配置發生改變的時候,咱們能夠經過訪問/refresh請求來刷新配置(由spring-boot-starter-actuator提供的監控功能)服務器
能夠看到這是咱們已經獲取到了最新的配置,當時這樣就存在一個問題,每個配置客戶端都須要刷新配置,會很是麻煩,也很容易出錯。解決方案由webhook來刷新配置,可是這個不是最好的解決辦法。可是咱們能夠經過消息總線來解決,這裏見會在下一篇文章中詳細講解,在這裏就不做贅述了。架構