源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all

一、config 简介

spring cloud config 分为服务端和客户端,服务端称为分布式配置中心,集中管理配置文件,客户端为各个业务单元,它们从配置中心获取相关配置,同时config 还实现了配置热更新,在服务不停机的情况下刷新配置。

二、项目结构

  • config-server: 配置中心;
  • config-client: 服务单元,可以从配置中心获取相关配置;
  • eureka: 注册中心。

三、config-server 配置中心的实现

3.1 导入依赖

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.heibaiying.config</groupId>
        <artifactId>spring-cloud-config</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>config-server</artifactId>

    <dependencies>
        <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>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.2 在启动类上添加@EnableDiscoveryClient和@EnableConfigServer 注解

@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
public class ConfigServerApplication {

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

}

3.3 指定注册中心地址,并配置git仓库地址的配置文件路径

server:
  port: 8020
# 指定注册中心地址
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8010/eureka/
# 指定服务命名
spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/heibaiying/spring-samples-for-all/
          search-paths: spring-cloud/spring-cloud-test-config/
          # 如果代码仓库是公开的 则 不需要设置用户名和密码
          username:
          password:
          # 指定拉取的配置文件的存放位置,配置文件最后存储的目录为 basedir + search-paths
          # 这个地方还需要注意的是,配置文件的仓库最好只放配置文件
          # 因为配置中心不仅会拉取search-paths下的文件,还会把uri指定仓库中的全部文件拉取到basedir下
          basedir: D:\git-config
      # 指定分支
      label: master

这里的git 仓库就是本用例的仓库,是公开的仓库,所以不用配置用户名和密码,配置文件如下

  • application.yml 为主配置;
  • application-dev.yml 为开发环境配置。

3.4 启动eureka和config-server服务,访问 http://localhost:8020/application-dev.yml

这里需要注意的拉取配置的时候,我们此时指定拉取的是dev配置,application.yml实际 配置如下:

这说明在用配置中心拉取配置的时候,和我们在本地开发的时候是一致的,配置是互补的,即dev中的实际配置应该是主配置和dev配置的结合,且遵循同名属性精确优先的原则。

3.5 http请求地址和资源文件映射

在本用例中如果我们想要直接访问主配置,用以下路径 http://localhost:8020/application.yml 是不行的,会得到错误页面。如果想要访问主配置,,可以用http://localhost:8020/application-X.yml,其中可以是任意字符,原因是:

请求地址和实际的配置文件应该遵循以下规则,application为配置文件名,profile 为环境,label为分支(如果不指定默认就是master分支)。

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

访问主配置:

四、config-client 搭建

4.1 导入依赖

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.heibaiying.config</groupId>
        <artifactId>spring-cloud-config</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>config-client</artifactId>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

4.2 新建 bootstrap.yml配置文件,指定注册中心地址和配置中心服务名,并在启动类上开启自动注册@EnableDiscoveryClient

这里需要特别说明的是,在之前的所有项目中我们采用的配置文件都是application.yml,但是这里一定要采用bootstrap.yml

假设我们的数据库配置是放在远程配置中心的,那么我们应该先去远程配置中心拉取配置,然后再去进行数据库的自动化配置,反之如果我们先进行了数据库的自动化配置,那么就会因为找不到url或驱动而抛出异常。

  • bootstrap.yml(bootstrap.properties)用来程序引导时执行,应用于更加早期配置信息读取,bootstrap.yml 先于 application.yml 加载。
  • application.yml(application.properties) 应用程序各个模块的配置信息。
server:
  port: 8030
spring:
  application:
    name: config-client
  cloud:
    config:
      discovery:
        enabled: true
        # 这里我们指定的是服务名 如果配置中心有多个,且用同一个服务名,我们的客户端拉取配置的时候是负载均衡的,配置中心也就是高可用的
        serviceId: config-server
      # 指定分支
      label: master
      # 指定环境
      profile: dev

# 注意指定注册中心的配置不要从公共配置中拉取,要在本地的配置文件中指定
# 因为我们必须要先从注册中心去获取可用的配置中心, 从配置中心去拉取配置
eureka:
    client:
      serviceUrl:
        defaultZone: http://localhost:8010/eureka/

@SpringBootApplication
@EnableDiscoveryClient
public class ConfigClientApplication {

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

}

4.3 创建配置映射类用于测试

@Component
@ConfigurationProperties(prefix = "programmer")
@Data
@ToString
public class Programmer{

    private String name;
    private int age;
    private boolean married;
    private Date hireDate;
    private float salary;
    private int random;
    private Map<String, String> skill;
    private List company;
    private School school;

}
@RestController
public class ConfigController {

    @Autowired
    private Programmer programmer;

    @RequestMapping("programmer")
    public String getProgrammer() {
        return programmer.toString();
    }
}

4.4 依次启动eureka,config-server,config-client ,访问 http://localhost:8030/programmer

这里需要注意是在启动eureka和config-server,要稍等一会在启动config-client,这里是为了确保config-server已经将服务注册到eureka,然后我们的config-client才能从eureka中获取配置中心的服务。

启动的时候可以从控制台看到如下拉取服务的信息:

Fetching config from server at : http://localhost:8020/
Located environment: name=config-client, profiles=[dev], label=master, version=50dcfb85cd751e4f28761cd6bad84c1f73034002, state=null

五、集成 spring-cloud-bus 实现配置热更新

5.1 消息总线简介

在微服务的架构中,我们通常想要构建一个共同的消息主题被所有微服务实例所监听,以便对所有微服务实例的管理和通知,这就是消息总线,spring cloud bus 就是消息总线的一种实现。

目前spring cloud bus 支持的消息中间件有 RabbitMQ和kafka, 我们下面的整合采用的是RrabbitMQ。

关于热更新只需要对配置客户端(config-client)做更改,不需要对(config-server)做改动。

5.1 导入bus依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<!--因为要用到端点功能(主要是刷新端点),所以需要导入actuator-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

5.2 修改bootstrap.yml 配置,开启总线配置,配置rabbitmq 和 开启热刷新端点

server:
  port: 8030
spring:
  application:
    name: config-client
  cloud:
    config:
      discovery:
        enabled: true
        # 这里我们指定的是服务名 如果配置中心有多个,且用同一个服务名,我们的客户端拉取配置的时候是负载均衡的,配置中心也就是高可用
        serviceId: config-server
      # 指定分支
      label: master
      # 指定环境
      profile: dev
    bus:
      #开启总线
      enabled: true
      # 打开ack跟踪的标志(默认关闭)
      trace:
        enabled: true
  # 使用bus实现热更新
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest

# 注意指定注册中心的配置不要从公共配置中拉取,要在本地的配置文件中指定
# 因为我们必须要先从注册中心去获取可用的配置中心, 然后从配置中心去拉取配置
eureka:
    client:
      serviceUrl:
        defaultZone: http://localhost:8010/eureka/

# 暴露热刷新的端点
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh

5.3 用@RefreshScope指定需要热刷新的配置

@Component
@ConfigurationProperties(prefix = "programmer")
@Data
@ToString
@RefreshScope // 定义下面配置热刷新范围
public class Programmer{

    private String name;
    private int age;
    private boolean married;
    private Date hireDate;
    private float salary;
    private int random;
    private Map<String, String> skill;
    private List company;
    private School school;

}

5.4 依次启动eureka,config-server, config-client 服务

在client服务端启动时候,可以在控制台 看到bus 自动创建了交换机、队列等

Created new connection: rabbitConnectionFactory#496c6d94:22/SimpleConnection@185d85d2 [delegate=amqp://guest@127.0.0.1:5672/, localPort= 63713]
o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-delete, or exclusive Queue (springCloudBus.anonymous.iY4TIIi9TSe0bL-TWAMhWg) durable:false, auto-delete:true, exclusive:true. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.

也可以在 rabbitmq 管控台查看

5.6 直接在 git 上修改配置文件,然后用 post 触发热刷新端点 http://localhost:8030/actuator/bus-refresh ,即可看到配置已经热刷新

注意: 这里的只能用 post 方式请求 ,可以用 postman 等测试软件

热刷新的过程在控制台有详细的打印,部分日志如下:

# 消息传播
Attempting to connect to: [127.0.0.1:5672]
Created new connection: rabbitConnectionFactory.publisher#b00f2d6:0/SimpleConnection@403c0406 [delegate=amqp://guest@127.0.0.1:5672/, localPort= 62748]
# 从配置中心拉取配置文件
Fetching config from server at : http://DESKTOP-8JGSFLJ:8020/
# 刷新应用上下文 AnnotationConfigApplicationContext
Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@62e12f66

附:源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all

spring cloud 系列第8篇 —— config+bus 分布式配置中心与配置热刷新 (F版本)的更多相关文章

  1. spring cloud 系列第2篇 —— eureka 高可用注册中心的搭建 (F版本)

    源码仓库地址:https://github.com/heibaiying/spring-samples-for-all 一.项目结构 eureka-server为服务注册中心,负责服务的管理: eur ...

  2. spring cloud系列教程第一篇-介绍

    spring cloud系列教程第一篇-介绍 前言: 现在Java招聘中最常见的是会微服务开发,微服务已经在国内火了几年了,而且也成了趋势了.那么,微服务只是指spring boot吗?当然不是了,微 ...

  3. Spring cloud系列教程第二篇:支付项目父工程图文搭建

    Spring cloud系列教程第二篇:支付项目父工程图文搭建 在讲解spring cloud相关的技术的时候,咱们就模拟订单支付这个流程来讲讲 在这个支付模块微服务搭建过程中,上面的这些技术,都会融 ...

  4. Spring Cloud系列教程第九篇-Eureka自我保护机制

    Spring Cloud系列教程第九篇-Eureka自我保护机制 本文主要内容: 1:自我保护介绍 2:导致原因分析 3:怎么禁止自我保护 本文是由凯哥(凯哥Java:kagejava)发布的< ...

  5. spring cloud 系列第1篇 —— eureka 服务的注册与发现 (F版本)

    源码仓库地址:https://github.com/heibaiying/spring-samples-for-all 一.eureka 简介 Spring Cloud Eureka使用Netflix ...

  6. spring cloud 系列第7篇 —— sleuth+zipkin 服务链路追踪 (F版本)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.简介 在微服务架构中,几乎每一个前端的请求都会经过多个服务单元协调来提 ...

  7. spring cloud 系列第6篇 —— zuul 服务网关 (F版本)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.zuul简介 1.1 API 网关 api 网关是整个微服务系统的门面 ...

  8. spring cloud 系列第5篇 —— hystrix+turbine 服务的熔断与监控 (F版本)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.hystrix 简介 1.1 熔断器 在分布式系统中,由于服务之间相互 ...

  9. spring cloud 系列第4篇 —— feign 声明式服务调用 (F版本)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.feign 简介 在上一个用例中,我们使用ribbon+restTem ...

随机推荐

  1. 关于ExpandableListView的一个小例子

    喜欢显示好友QQ那样的列表,可以展开,可以收起,在android中,以往用的比较多的是listview,虽然可以实现列表的展示,但在某些情况下,我们还是希望用到可以分组并实现收缩的列表,那就要用到an ...

  2. java 子类重写父类的方法

    若想实现一个合格重写方法,而不是重载,那么必须同时满足下面的要求! A.重写规则之一:重写方法不能比被重写方法限制有更严格的访问级别. (但是可以更广泛,比如父类方法是包访问权限,子类的重写方法是pu ...

  3. DDD实战9 经销商领域上下文

    1.创建Dealer.Domain 类库项目 2.创建实体和值对象 3.安装ef的包 4.创建上下文接口(IDealerContext)之所以要创建上下文接口,是为了可替换,在其他项目总使用接口,当需 ...

  4. 安德鲁斯Launcher得到的装在手机的应用程序列表

    Launcher最基本的是让所有的应用程序和入口图标的列表.有两种方法来获得,一般: PackageInfo ResolveInfo 执行获取全部APP的Launcher而且同意进行点击事件,进入到应 ...

  5. EPPlus简单使用

    在使用之前需要在项目中添加对EEPULS.dll的引用 1,创建excel 2,创建sheet 3,添加内容 4,修改 5,保存 FileInfo newFile = new FileInfo(fil ...

  6. Android Fragment——详细解释

    1.Fragment概述 在一个Activity中. Fragment代表UI的一个部分或者一个行为.一个Activity能够结合多个Fragment对象,也能够在多个activity中使用同样Fra ...

  7. HQL链接查询

    和SQL查询一样,HQL也支持各种各样的连接查询,如内连接.外连接.我们知道在SQL中可通过join字句实现多表之间的连接查询.HQL同样提供了连接查询机制,还允许显示指定迫切内连接和迫切左外连接.H ...

  8. linux之tail -F命令异常file truncated

    使用tail -F收集日志时,经常报出file truncated, 导致日志又重新读取.tail: `test.out' has appeared;  following end of new fi ...

  9. CefSharp For WPF隐藏滚动条

    效果:开始的时候会显示几秒,之后就不会再显示了 <!--浏览器--> <cefSharpWPF:ChromiumWebBrowser Name="webBrowser&qu ...

  10. glibc内存管理方式

    程序员接触的内存空间和系统接触的物理内存空间是有所区别的.对于一般进程来讲,他面对的是一个线性虚拟内存空间:地址从0到最大值.每一个进程面对的虚拟内存空间都是一样的,都享有全部的内存地址.虚拟内存空间 ...