SpringCloud之Config

前面的話】本文的某些知識依賴個人微服務系列文章,若是沒有看過能夠先移步去看一下。在前面的應用當中,咱們全部的配置都是寫在yaml配置文件當中的,這樣就會形成幾個問題:安全、統一管理等等。而SpringCloud也是考慮到這一點,給出的方案就是Spring Cloud Configjava


壹、Config的簡介

Spring Cloud Config是Spring Cloud團隊建立的一個全新項目,用來爲分佈式系統中的基礎設施和微服務應用提供集中化的外部配置支持,它分爲服務端與客戶端兩個部分。其中服務端也稱爲分佈式配置中心,它是一個獨立的微服務應用,用來鏈接配置倉庫併爲客戶端提供獲取配置信息、加密/解密信息等訪問接口;而客戶端則是微服務架構中的各個微服務應用或基礎設施,它們經過指定的配置中心來管理應用資源與業務相關的配置內容,並在啓動的時候從配置中心獲取和加載配置信息。Spring Cloud Config實現了對服務端和客戶端中環境變量和屬性配置的抽象映射,因此它除了適用於Spring構建的應用程序以外,也能夠在任何其餘語言運行的應用程序中使用。因爲Spring Cloud Config實現的配置中心默認採用Git來存儲配置信息,因此使用Spring Cloud Config構建的配置服務器,自然就支持對微服務應用配置信息的版本管理,而且能夠經過Git客戶端工具來方便的管理和訪問配置內容。固然它也提供了對其餘存儲方式的支持,好比:SVN倉庫、本地化文件系統。git

貳、準備工做

  • 首先在工程下面新建lovin-config-repo,做爲存放配置文件的地方,而且添加dev,test,pro的相關配置文件,最後在配置文件中添加token的配置,具體見下圖

新建配置中心
添加token配置

  • 新建一個config的服務端子工程lovin-config-server,用於後面的操做。下面是主要的pom依賴:
<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>
  • 這裏爲了安全,我這裏仍是添加spring-boot-starter-security
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服務地址
  • 上面的配置文件是用git做爲配置文件管理中心,還有svn和本地文件系統兩種,我這裏也在下面簡單羅列如下:

git版本配置

spring:
    cloud:
      config:
        server:
          git:
            uri: https://github.com/lovinstudio/lovincloud
            search-paths: lovin-config-repo
            username: #若是是私人倉庫,還須要配置用戶名,公共倉庫能夠省略
            password: #若是是私人倉庫,還須要配置密碼,公共倉庫能夠省略
        label: master

svn版本配置

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
  • 配置spring-boot-starter-security,這裏爲了方便我這裏放開全部請求
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();
    }
}
  • 在主類上添加@EnableConfigServer,固然也須要註冊到註冊中心:
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);
    }
}

叄、啓動測試

  • 依次啓動eureka的服務端和新建的lovin-config-server
  • 訪問地址:http://chirius:8886/lovin-config/dev。
  • 結果原始數據:
{"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-boot-starter-security的配置
  1. 新建bootstrap.yml
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中見會讀取不到配置
  1. 添加application.yml
server:
  port: 8807   # 服務端口號
spring:
  application:
    name: lovinconfigclient     # 服務名稱
  security:
    basic:
      enabled: true
    user:
      name: lovin
      password: ${REGISTRY_SERVER_PASSWORD:lovin}
  • 配置spring-boot-starter-security,這裏爲了方便我這裏放開全部請求
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);
    }
}
  • 添加ConfigController用來測試獲取配置
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來刷新配置,可是這個不是最好的解決辦法。可是咱們能夠經過消息總線來解決,這裏見會在下一篇文章中詳細講解,在這裏就不做贅述了。架構


相關文章
相關標籤/搜索