SpringCloud Config是为微服务框架提供微服务集中化的外部配置支持,配置服务器为各个不同服务器应用的所有环境提供了一个中心化的外部配置。

springcloud config除了以github作为配置存储之外,还可以用数据库、svn/本地文件等作为存储。

 Spring Cloud Config分为服务端和客户端。

服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取的配置信息,加密/解密信息等访问接口。

客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。

配置服务器默认采用git来存储配置信息 ,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。

实现最简单的配置中心

最简单的配置中心,就是启动一个服务作为服务方,之后各个需要获取配置的服务作为客户端来这个服务方获取配置。

1,先在github中建立配置文件

创建仓库,目录结构如下:

 配置文件的内容大致如下,用于区分

data:
  env: config-single-dev
  user:
    password: dev10
    username: single-client-user

2,创建配置中心服务端

1,新建Spring Boot项目

2,POM文件

<dependencies>
        <!--spring cloud config server包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

3,YML文件配置

bootstrap.yml文件

spring:
  application:
    name: config-single-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/flygoldfish/cloud2020-config.git
          search-paths: config
          default-label: main

application.yml

server:
  port: 3001

4,主启动类

@SpringBootApplication
@EnableConfigServer
public class ConfigMain {
    public static void main(String[] args) {
        SpringApplication.run(ConfigMain.class,args);
    }
}

5,启动服务,测试。

Spring Cloud Config有一套访问规则,通过这套规则在浏览器上直接访问就可以。

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
  • {application}就是应用名称,对应到配置文件上来,就是配置文件的名称部分。
  • {profile}就是配置文件的版本。项目有开发版本、测试环境版本、生产环境版本,对应到配置文件上了就是以application-{profile}.yml加以区分,如application-dev.yml、application-sit.yml、application-prod.yml。
  • {label}表示git分支,默认是main分支,如果项目是以分支做区分也是可以的,那就可以通过不同的label来控制不同的配置文件。

上面的5条规则中,只有前3条的配置文件是yml格式的,如果根据这3条规则进行访问,并返回数据,说明配置中心服务端一切正常。

  1. http://localhost:3001/config-single-client/dev/main
  2. http://localhost:3001/config-single-client/prod
  3. http://localhost:3001/config-single-client-dev.yml

3,创建配置中心客户端,使用配置

1,新建项目

2,POM文件

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- spring cloud config 客户端包 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

3,YML文件

bootstrap.yml

spring:
  profiles:
    active: dev

---
spring:
  application:
    name: config-single-client
  cloud:
    config:
      label: main
      profile: prod
      uri: http://localhost:3001


---
spring:
  application:
    name: config-single-client
  cloud:
    config:
      uri: http://localhost:3001
      label: main
      profile: dev

配置了两个版本的配置,并通过spring.profiles.active设置当前使用的版本。

application.yml

server:
  port: 3002
management:
  endpoint:
    shutdown:
      enabled: false
  endpoints:
    web:
      exposure:
        include: "*"

data:
  env: NaN
  user:
    username: NaN
    password: NaN

其中management是关于actuator相关的,接下来自动刷新配置的时候需要使用。

data部分是无法读取配置中心的配置时,使用此配置,以免项目无法启动。

4,启动类

@SpringBootApplication
public class ConfigClient3002Main {
    public static void main(String[] args) {
        SpringApplication.run(ConfigClient3002Main.class,args);
    }
}

5,要读取配置中心的内容,需要增加相关的配置类,Spring Cloud Config读取配置中心内容的方式和读取本地文件中的配置是一模一样的。可以通过@Value或@ConfigurationProperties来获取。

使用@Value的方式

@Component
public class GitConfig {
    @Value("${data.env}")
    private String env;
    @Value("${data.user.username}")
    private String name;
    @Value("${data.user.password}")
    private String password;

    @Override
    public String toString() {
        return "GitConfig{" +
                "env='" + env + '\'' +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEnv() {
        return env;
    }

    public void setEnv(String env) {
        this.env = env;
    }
}

使用@ConfigurationProperties的方式

@Component
@ConfigurationProperties(prefix = "data")
public class GitAutoConfig {
    private String dev;
    private User user;

    @Override
    public String toString() {
        return "GitAutoConfig{" +
                "dev='" + dev + '\'' +
                ", user=" + user +
                '}';
    }

    public static class User{
        private String username;
        private String password;

        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }

    public String getDev() {
        return dev;
    }

    public void setDev(String dev) {
        this.dev = dev;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

6,增加一个RESTController来测试使用配置

@RestController
public class GitController {

    @Autowired
    private GitConfig gitConfig;

    @Autowired
    private GitAutoConfig gitAutoConfig;

    @GetMapping("/gitConfig")
    public GitConfig getGitConfig(){
        return gitConfig;
    }

    @GetMapping("/gitAutoConfig")
    public GitAutoConfig getGitAutoConfig(){
        return gitAutoConfig;
    }
}

7,启动项目,测试

实现自动刷新

Spring Cloud Config在项目启动时加载配置内容这一机制,导致了它存在一个缺陷,修改配置文件内容后,不会自动刷新。它提供了一个刷新机制,但是需要主动触发。那就是@RefreshScope注解结合actuator使用,注意要引入spring-boot-starter-actuator包。

1,在config client端配置中增加actuator配置。

management:
  endpoint:
    shutdown:
      enabled: false
  endpoints:
    web:
      exposure:
        include: "*"

主要这里主要用到的是refresh这个接口

2,在需要读取配置的类上增加@RefreshScope注解。

@RestController
@RefreshScope
public class GitController {

    @Autowired
    private GitConfig gitConfig;

    @Autowired
    private GitAutoConfig gitAutoConfig;

    @GetMapping("/gitConfig")
    public GitConfig getGitConfig(){
        return gitConfig;
    }

    @GetMapping("/gitAutoConfig")
    public GitAutoConfig getGitAutoConfig(){
        return gitAutoConfig;
    }
}

注意,以上都是在client端做的修改。

每次github上的配置内容修改之后,需要手动发送post请求到http://localhost:3002/actuator/refresh,然后客户端才可以获取到最新修改后的数据。另外,@Value注解注入的值方式,刷新后还是旧数据,所以在项目中就不要使用@Value这种方式加载配置了。

使用Spring Cloud Bus来自动刷新多个客户端

Spring Cloud Bus将分布式系统的节点与轻量级消息代理链接。这可以用于广播状态更改(如配置更改)或其他管理指令。一个关键的想法是,Bus就像一个扩展的Spring Boot应用程序的分布式执行器,但也可以用作应用程序之间的通信渠道。

1,Spring Cloud Bus核心原理其实就是利用消息队列做广播,所以要先有个消息队列,目前官方支持RabbitMQ和kafka。

配置好RabbitMQ,使用http://localhost:15672访问UI管理界面。

2,POM文件添加amqp,config服务端和客户端都需配置。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

3,YML文件添加RabbitMQ相关配置,默认端口5672。

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

另外,配置actuator相关信息

config客户端

management:
  endpoint:
    shutdown:
      enabled: false
  endpoints:
    web:
      exposure:
        include: "*"

config服务端

management:
  endpoint:
    shutdown:
      enabled: false
  endpoints:
    web:
      exposure:
        include: "bus-refresh"

4,启动服务端,启动两个或多个client端,测试。

在启动的时候分别加上vm option:-Dserver.port=3002和-Dserver.port=3003,然后分别启动就可以了。

5,访问其中的一个actutor/bus-refresh地址(最好是config服务端,如:http://localhost:3001/actoator/bus-refresh),注意还是要用POST方式访问。这样,github修改的内容就可以动态访问了。

结合Eureka使用Spring Cloud Config

1,在github仓库中增加配置文件

 1,POM文件

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>
    </dependencies>

2,YML文件

server:
  port: 7001

spring:
  application:
    name: cloud-eureka-server
eureka:
  client:
    fetch-registry: false
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
  instance:
    hostname: eureka7001.com

3,启动类

@SpringBootApplication
@EnableEurekaServer
public class EurekaServer7001Main {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer7001Main.class,args);
    }
}

4,启动服务

2,配置Spring Cloud Config服务端

1,POM文件

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--spring cloud config server包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
    </dependencies>

2,YML文件

server:
  port: 3001

spring:
  application:
    name: config-single-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/flygoldfish/cloud2020-config.git
          search-paths: config
          default-label: main

  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest


management:
  endpoint:
    shutdown:
      enabled: false
  endpoints:
    web:
      exposure:
        include: 'bus-refresh'

eureka:
  instance:
    instance-id: config3001
    prefer-ip-address: true
    lease-expiration-duration-in-seconds: 90
    lease-renewal-interval-in-seconds: 30
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
    fetch-registry: true
    register-with-eureka: true

3,主启动类

@SpringBootApplication
@EnableConfigServer
@EnableEurekaClient
public class ConfigMain {
    public static void main(String[] args) {
        SpringApplication.run(ConfigMain.class,args);
    }
}

4,启动服务,之后访问Eureka,可以看到服务已注册成功。

3,配置Spring Cloud Config客户端

1,POM文件

    <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-web</artifactId>
        </dependency>
        <!-- spring cloud config 客户端包 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</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-bus-amqp</artifactId>
        </dependency>
    </dependencies>

2,YML文件

application.yml

server:
  port: 3002
management:
  endpoint:
    shutdown:
      enabled: false
  endpoints:
    web:
      exposure:
        include: "*"

data:
  env: NaN
  user:
    username: NaN
    password: NaN

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
  instance:
    instance-id: configclient3002
    prefer-ip-address: true
    lease-expiration-duration-in-seconds: 90
    lease-renewal-interval-in-seconds: 

bootstrap.yml

spring:
  profiles:
    active: dev

---
spring:
  application:
    name: config-single-client
  cloud:
    config:
      label: main
      profile: prod
      uri: http://localhost:3001


---
spring:
  application:
    name: config-single-client
  cloud:
    config:
      uri: http://localhost:3001
      label: main
      profile: dev

3,主启动类

@SpringBootApplication
@EnableEurekaClient
public class ConfigClient3002Main {
    public static void main(String[] args) {
        SpringApplication.run(ConfigClient3002Main.class,args);
    }
}

4,其他部分与前面的一样,没有任何更改。

5,启动客户端。

注意事项:

1,在git上配置文件的名字要和config的client端的application name对应。

2,在结合eureka的场景中,关于eureka和git config相关的配置要放在bootstrap.yml中,否则会请求默认的config server配置,这是因为当你加了配置中心,服务就要先去配置中心获取配置,这个时候,application.yml配置文件还没有开始加载,而bootstrap.yml是最先加载的。

 

 posted on 2021-01-08 16:58  会飞的金鱼  阅读(149)  评论(0)    收藏  举报