springcloud Config 配置中心实现

1.前言

Spring Cloud Config为分布式系统中的外部化配置提供服务器端和客户端支持。使用Config Server,您可以在中心位置管理所有环境中应用程序的外部属性。客户端和服务器上的概念与Spring Enviroment和PropertySource抽象,因此它们非常适合Spring应用程序,而且可以与以任何语言运行的任何应用程序一起使用。在应用程序从开发人员到测试人员再到生产人员的整个部署过程中,您可以管理这些环境之间的配置,并确保应用程序具有它们迁移时所需的一切。服务器存储后端的默认实现使用git,因此它轻松支持带标签的配置环境版本,并且可以通过各种工具来访问这些内容来管理内容。添加替代实现并将其插入Spring配置很容易。

Spring Cloud Config 是 Spring Cloud 家族中最早的配置中心,虽然后来又发布了 Consul 可以代替配置中心功能,但是 Config 依然适用于 Spring Cloud 项目,通过简单的配置即可实现功能。

目前有一些用的比较多的开源的配置中心,比如携程的 Apollo、蚂蚁金服的 disconf 等,对比 Spring Cloud Config,这些配置中心功能更加强大。有兴趣的可以拿来试一试。

2.实现最简单的配置中心

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

2.1 在GitHub上创建一个配置中心仓库

目录结构如下:

配置文件大致如下:

server:
  port: 9090

eurekaServer:
  port: 6662
feign:
  client:
    provide:
      name: configtest-feign-local

 2.2 创建配置中心服务端

新建一个springboot项目,引入config-server 和 starter-web

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

 2.2 配置Config

bootstrap.yml:

spring:
  application:
    name: cloud-config-server
  cloud:
    config:
      server:
        git:
          uri: 你配置中心仓库的GitHub地址
          username: yourUserName
          password: yourPassword
          default-label: master #配置文件分支
          search-paths: cloud-config-client  #配置文件所在根目录

2.3在 Application 启动类上增加相关注解 @EnableConfigServer

@SpringBootApplication
@EnableConfigServer
public class CloudConfigServerApplication {

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

}

2.4启动服务,测试

从springcloud官网 :https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.2.2.RELEASE/reference/html/

可以看到,springcloud Config 有一套它的访问规则:

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

我们在浏览器中可以直接看的,但是为了美观,我用postman试了一下:

其他几种规则我也试过了,都是可以的,在这里我就不一一截图了。

3.实现配置中心客户端,使用配置中心服务端

配置中心服务端好了,配置数据准备好了,接下来,就要在我们的项目中使用它了。

3.1新建新的springboot项目

引入starter-web和starter-config依赖,跟服务端一样。

3.2初始化配置文件

bootstrap.yml:

spring:
  application:
    name: cloud-config-client
  cloud:
    config:
      uri: http://localhost:8760
      label: master
      profile: local

application.yml:

server:
  port: 9999
spring:
  profiles:
    active: local
eurekaServer:
  port: localPort
feign:
  client:
    provide:
      name: localName

3.3增加测试接口

@Component
@Data
public class GitConfig {

    @Value("${eurekaServer.port}")
    public String port;

    @Value("${feign.client.provide.name}")
    public String providerName;

}
@RestController
@RequestMapping("/config")
public class ConfigController {
    @Resource
    private GitConfig gitConfig;

    @GetMapping("/test01")
    public String test01() {
        String result = gitConfig.port + " : " + gitConfig.providerName;
        System.out.println(result);
        return result;
    }
}

3.4测试

启动项目,测试:

可以看到,返回的数据是从配置中心仓库里的数据,测试通过!

Spring Cloud Config 在项目启动时加载配置内容这一机制,导致了它存在一个缺陷,修改配置文件内容后,不会自动刷新。例如我们上面的项目,当服务已经启动的时候,去修改 github 上的配置文件内容,这时候,再次刷新页面,对不起,还是旧的配置内容,新内容不会主动刷新过来。
但是,总不能每次修改了配置后重启服务吧。如果是那样的话,还是不要用它了为好,直接用本地配置文件岂不是更快。

它提供了一个刷新机制,但是需要我们主动触发。那就是 @RefreshScope 注解并结合 actuator ,注意要引入 spring-boot-starter-actuator 包。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>      

在 config client 端配置中增加 actuator 配置:

management:
  endpoints:
    web:
      exposure:
        include: '*'
    enabled-by-default: true
  metrics:
    tags:
      application: ${spring.application.name}
      environment: ${spring.profiles}

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

@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
    @Resource
    private GitConfig gitConfig;

    @GetMapping("/test01")
    public String test01() {
        String result = gitConfig.port + " : " + gitConfig.providerName;
        System.out.println(result);
        return result;
    }
}

重启client端后修改GitHub上的配置文件,再来使用postman测试,发现并没有更改,查阅资料发现是因为我使用了@Value,如果换成@ConfigurationProperties注解就咩问题了,至于为什么,有时间再整理个文章,嘿嘿:

其实自动刷配置的方式有很多,如Webhooks、springcloud Bus等,有兴趣的话大家可以了解一下。

5.结合Eureka实现springcloud Config

以上讲了 Spring Cloud Config 最基础的用法,但是如果我们的系统中使用了 Eureka 作为服务注册发现中心,那么 Spring Cloud Config 也应该注册到 Eureka 之上,方便其他服务消费者使用,并且可以注册多个配置中心服务端,以实现高可用。

 那么我们下面就会将springcloud Config集成到Eureka。

5.1创建eureka注册中心

简单讲一下如何新建一个eureka注册中心,

引入相关依赖:

        <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-test</artifactId>
			<scope>test</scope>
		</dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>

启动类加上@EnableEurekaServer注解,

配置:

server:
  port: 8761

eureka:
  instance:
    hostname: localhost
    appname: registrationCenter
  client:
    register-with-eureka: false  # 单点的时候设置为 false 禁止注册自身
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

5.2将配置中心服务端注册到eureka

添加依赖:

        <dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>

启动类增加注解:@EnableEurekaClient。

增加eureka配置:

eureka:
  server:
    max-time-for-replication: 30000
  client:
    register-with-eureka: true  #将此项目注册到Eureka服务
    service-url:
      defaultZone: http://localhost:8761/eureka/    #注册地址
    fetch-registry: true

5.2将配置中心客户端注册到eureka

跟服务端一样,添加依赖,添加注解,增加eureka配置;

除此之外,还要配置与服务端的关系,这里我们不再使用config.uri了,而是使用service-id属性:

spring:
  application:
    name: cloud-config-client
  cloud:
    config:
      label: master
      profile: local
      discovery:
        enabled: true
        service-id: cloud-config-server

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

5.3启动项目测试:

可以看到我们的服务端和客户端都注册上啦。

接下来在postman上试一下:

也是OK的!

这里有几点是需要大家注意的:

  • 配置中心仓库内配置文件所在文件夹要跟服务端配置的search-paths一致,这里后面再研究下怎么优化成动态的匹配;
  • 在继承eureka的时候,关于eureka和git config的配置要放在bootstrap.yml 中,否则会请求默认的 config server 配置,这是因为当你加了配置中心,服务就要先去配置中心获取配置,而这个时候,application.yml 配置文件还没有开始加载,而 bootstrap.yml 是最先加载的。

另外,在这里记录一下我的作死经历,因为在本地启动微服务项目的时候,每次都要起很多服务,Eureka注册中心啊、ConfigServer啊,所以觉得很麻烦,于是我把这两个服务放到了我的腾讯云服务器上,然后在本地启动ConfigClient,于是问题出现了:

连接不上,这是为什么呢?仔细一看,这个地址是我服务器内网的地址,并不是外网的地址,再去eureka上看了一眼,果然是。不通是正常的。。暂时还没有想到有啥办法将eureka上注册的地址改成外网地址,也没想到办法在我本地将内网地址映射成外网地址,如果是域名的话,倒是可以通过修改hosts文件达到我们的目的。所以我只能暂时只使用服务器上的注册中心,ConfigServer只能在本地起了,事实证明遮掩是可行的。

其实如果我同时起了本地和服务器上的Configserver的话,它第一次连接服务器端的Configserver超时了会继续重试,下一次就会试着连接我本地的Configserver,就会成功了。

这是我eureka上已经注册的服务:

看一下效果:

延伸阅读:

这在里,我们项目读取的配置文件路径是写死的,不能做动态的匹配,这篇文章会告诉大家如何优化:

如何动态配置不同的项目从springcloud Configration配置中心拉取配置的根路径

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值