带你一步步实现springcloud微服务集中式配置管理

/ 默认分类 / 0 条评论 / 875浏览

微服务中需要解决的一些问题

一.日志收集

待更新

二.自动化运维(部署发布)

待更新

三.集中化配置

为什么要进行集中化配置

使用spring-cloud-config实现配置的集中式管理

我们可以发现,每一个微服务都是从springcloudconfig的server端获取配置,springcloudconfig的server端会从提前配置的远程git仓库获取配置,当然为了防止远程仓库异常,我们也可以配置一个本地仓库

配置springcloudconfig服务端

  1. pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>com.zuo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>zuo.configserver</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--加入config server依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <!--加入eruka客户端依赖-->
        <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>

  1. application.yml配置文件
spring:
  application:
    name: configserver
  cloud:
    config:
      server:
        git:
          uri: https://github.com/codeManZuo/configtest/  
          search-paths: 
            - myconfig   #(数组的方式)查找配置信息去哪个目录下
          username: 1045612224@qq.com
          password: 程序员大晖的github密码呀呀呀
          force-pull: true
          default-label: master  #默认去哪个分支
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true
    ip-address: 127.0.0.1
server:
  port: 8022

uri: https://github.com/codeManZuo/configtest/: 配置服务端去哪个远程git仓库拉取配置文件,这里的路径是到仓库的根路径(直接截取浏览器href),参考下面是我设置的测试仓库的截图

search-paths: - myconfig:这是设置被允许的springcloudconfigserver可以去的远程仓库的目录下查找

所以说上面配置的这个myconfig是远程仓库的某个目录,并且需要注意的是这个目录要和带有springcloudconfigclient的微服务名字一样,后面介绍为什么

  1. 启动类

springcloudconfigserver作为一个微服务存在,也是需要一个启动类的

@SpringBootApplication
@EnableConfigServer //启动集中式配置的服务端
@EnableDiscoveryClient
public class ConfigServerApplication {

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

}

  1. 添加集中式的配置文件

在我们的远程的配置仓库中添加准备好的几个用于本次测试的配置文件,这里为了操作方便我将前面那个放置配置文件的远程仓库拉取到了我的idea中

  1. 启动测试服务端搭建情况

启动configserver这个微服务之后我们可以按照下面的请求路径规范来测试

上图出自<<springcloud与docker微服务架构实战>>

上面其实就是实际中我们的springcloudconfigserver去远程仓库拉取配置文件的请求路径 最前面的路径是微服务的名字,所以这里我们知道前面为什么我们说仓库下面的那个目录需要使用的是我们的微服务的名字了吧,随后可以跟上环境比如dev还是test,最后可以跟上仓库的分支

所以按照上面的设置我们现在的请求路径就是:

localhost:8022/myconfig/dev

ok,我们的服务端搭建完毕!!

配置具有config客户端功能的微服务

这里我们创建一个小demo当做是一个具有springcloudconfigclient功能(也就是可以从springcloudconfigserver上获取集中式配置的功能)的微服务(比如上传功能的微服务,登录的微服务等等)

  1. pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>com.zuo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>zuo.configclient</groupId>
    <artifactId>configclient</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>configclient</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--加入config server依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>
        <!--加入eruka客户端依赖-->
        <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>

2.bootstrap.yml配置文件

spring:
  application:
    name: myconfig
  cloud:
    config:
      uri: http://127.0.0.1:8022/
      profile: dev
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true
    ip-address: 127.0.0.1
server:
  port: 8023

这里我的微服务的名字叫做myconfig,前面的目录的名字和请求路径都是需要和这个名字一致的

为什么是配置bootstrap.yml而不是application.yml??? 网上的解释大多这样:

Spring Boot服务启动时会加载application.yml/application.properties配置文件,Spring Cloud中有”引导上下文“的概念,引导上下文会加载bootstrap.yml/bootstrap.properties配置文件,即bootstrap.yml/bootstrap.properties会在Spring Boot服务启动之前加载,具有更高的优先级。默认情况下bootstrap.yml/bootstrap.properties中的属性不能被覆盖。

所以比如我们需要动态改变微服务启动的接口,我们就可以在bootstrap.yml中这样:

server:
  port: ${zuohui}
  1. 测试使用的controller
package zuo.configclient.a;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @Value("${zuohui}")
    private String value;

    @GetMapping("/mydev")
    public void getDev()
    {
        System.out.println("进入controler");
        System.out.println("======="+value);
    }

}

href:http://127.0.0.1:8666/mydev 结果:

配置修改后服务自动刷新(/refresh单个刷新)

比如前面那个config的客户端启动后再运行期间,需要改动git远程仓库中的配置,比如某些value值得改变,这个时候我们更改git仓库后当前这个config客户端微服务是没有及时更新的,这里就是需要用到

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>

在configclient微服务中加入上面的依赖,再将controller改为:

@RestController
@RefreshScope   //添加这个注解
public class MyController {

    @Value("${zuohui}")
    private String value;

    @GetMapping("/mydev")
    public void getDev()
    {
        System.out.println("进入controler");
        System.out.println("======="+value);
    }

}

这样我们更改远程仓库中的配置文件后,如果希望及时生效就可以随后访问一下 localhost:8666/refresh 之后在访问http://127.0.0.1:8666/mydev就会发现配置以及生效了

配合使用springcloud bus实现所有自动刷新

因为微服务数量可能很多,按照前面的方式会需要很多步骤,所以这里我们可以让客户端整合springcloudbus,这样就可以做到一个微服务接收到了/bus/refresh,其他所有的微服务都可以接受到来自消息队列的/bus/refresh刷新,达到热部署的效果

  1. 安装好rabbitMQ,可以直接使用docker安装,简单高效
  2. 配置我们的rabbitMQ
spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
  1. 导入依赖
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bus-amqp -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
    <version>2.2.1.RELEASE</version>
</dependency>

  1. 将上面配置好的configclient的微服务复制一个,设置端口号为8777
  2. 之后我们先修改git中的配置文件的信息然后访问 localhost:8666/bus/refresh 然后访问localhost:8666/mydev 发现配置改变生效了, 并且访问: localhost:8777/mydev 发现配置也是生效了

选择式刷新微服务

其实前面说的 localhost:8666/bus/refresh后面可以跟上参数来指定我们需要生效的微服务

/bus/refresh?destination=ApplicationContextID

ApplicationContextID指的是各个微服务的 服务名:端口号

所以上面的我们可以是

/bus/refresh?destination=myconfig:8666



说明:以上所有demo项目具有一个maven父项目作为版本控制