美文网首页我爱编程
Spring Cloud构建微服务架构--分布式配置中心

Spring Cloud构建微服务架构--分布式配置中心

作者: 丁庆华 | 来源:发表于2018-05-21 15:25 被阅读0次

Spring Cloud Config为服务端和客户端提供了分布式系统的外部化配置支持。配置服务器为各应用的所有环境提供了一个中心化的外部配置。它实现了对服务端和客户端对Spring Environment和PropertySource抽象的映射,所以它除了适用于Spring构建的应用程序,也可以在任何其他语言运行的应用程序中使用。作为一个应用可以通过部署管道来进行测试或者投入生产,我们可以分别为这些环境创建配置,并且在需要迁移环境的时候获取对应环境的配置来运行。

配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。当然他也提供本地化文件系统的存储方式,下面从这两方面介绍如何使用分布式配置来存储微服务应用多环境的配置内容。

构建Config-Server

  • 通过Spring Cloud构建一个Config Server,非常简单,只需要三步:

pom.xml中引入spring-cloud-config-server依赖,完整依赖配置如下:

<?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>

    <groupId>com.misrobot</groupId>
    <artifactId>config-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>config-server</name>
    <description>spring cloud config 服务端</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Edgware.SR3</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

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

  • 创建Spring Boot的程序主类,并添加@EnableConfigServer注解,开启Config Server
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@EnableConfigServer
@SpringBootApplication
public class ConfigCenterApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigCenterApplication.class, args);
    }
}
  • application.yml中配置服务信息以及git信息,例如:
spring:
  application:
    name: config-center

  # git管理配置
  cloud:
    config:
      server:
        git:
          uri: https://github.com/dhappy05/spring-cloud/    #配置git仓库位置
          search-paths: spring-cloud-config-demo/config-repo       #配置仓库路径下的相对搜索位置,可以配置多个
          username: username       #访问git仓库的用户名
          password: password       #访问git仓库的用户密码

server:
  port: 7001

#配置文件的命名格式为:{application}-{profile}.properties
#启动服务端后可通过http://localhost:7001/configcenter/prod/master来测试
#其中configcenter对应到配置文件名中的application,prod对应到配置文件的profile,master对应到git的分支

到这里,使用一个通过Spring Cloud Config实现,并使用git管理内容的配置中心已经完成了,启动该应用,成功后开始的验证。

服务端验证

为了验证上面完成的配置服务器,在[https://github.com/dhappy05/spring-cloud/tree/master/spring-cloud-config-demo/)下创建了一个config-repo目录作为配置仓库,并根据不同环境新建了下面四个配置文件:

  • configcenter.properties
  • configcenter-dev.properties
  • configcenter-test.properties
  • configcenter-prod.properties

其中设置了一个from属性,为每个配置文件分别设置了不同的值,如:

  • from=git-default-1.0
  • from=git-dev-1.0
  • from=git-test-1.0
  • from=git-prod-1.0

为了测试版本控制,在master中,我们都加入1.0的后缀,同时创建一个test分支,并将各配置文件中的值用2.0作为后缀。

完成了这些准备工作之后,我们就可以通过浏览器或POSTMAN等工具直接来访问到我们的配置内容了。

URL与配置文件的映射关系如下:

  • /{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来访问不同的配置内容,比如:要访问test分支,didispace应用的prod环境,可以通过这个url:http://localhost:7001/configcenter/prod/test

{
    "name": "configcenter",
    "profiles": [
        "prod"
    ],
    "label": "master",
    "version": "2f8d8ef45e5d69540aec0584bed16b4cae56fb42",
    "state": null,
    "propertySources": [
        {
            "name": "https://github.com/dhappy05/spring-cloud/spring-cloud-config-demo/config-repo/configcenter-prod.properties",
            "source": {
                "from": "git-prod-1.0"
            }
        },
        {
            "name": "https://github.com/dhappy05/spring-cloud/spring-cloud-config-demo/config-repo/configcenter.properties",
            "source": {
                "from": "git-default-1.0"
            }
        }
    ]
}

微服务端映射配置

在完成并验证了配置服务中心之后,下面看看我们如何在微服务应用中获取配置信息。

  • 创建一个Spring Boot应用,在pom.xml中引入spring-cloud-starter-config依赖,完整依赖关系如下:
<?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>

    <groupId>com.misrobot</groupId>
    <artifactId>config-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>config-client</name>
    <description>spring cloud config client</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
        <!--<version>1.3.5.RELEASE</version>-->
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Edgware.SR3</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</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-starter-actuator</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • 创建最基本的Spring Boot启动主类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConfigClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigClientApplication.class, args);
    }
}
  • 创建bootstrap.properties配置,来指定config server,例如:
spring:
  application:
    name: configcenter   #对应配置文件中的{application}部分

  cloud:
    config:
      label: master   #对应前配置文件的git分支
      profile: prod   #对应前配置文件中的{profile}部分
      uri: http://localhost:7001/   #配置中心的地址

server:
  port: 7002

# 若不添加以下配置,则用post方式访问http://localhost:7002/refresh时会出现报错:Full authentication is required to access this resource
#另一种方式是在maven中添加spring-boot-starter-security依赖,并开启HTTP basic认证认证
management:
  security:
    enabled: false


#这里需要格外注意:上面这些属性必须配置在bootstrap.properties中,config部分内容才能被正确加载。
#因为config的相关配置会先于application.properties,而bootstrap.properties的加载也是先于application.properties。
  • spring.application.name:对应前配置文件中的{application}部分
  • spring.cloud.config.profile:对应前配置文件中的{profile}部分
  • spring.cloud.config.label:对应前配置文件的git分支
  • spring.cloud.config.uri:配置中心的地址
这里需要格外注意:上面这些属性必须配置在bootstrap.properties中,config部分内容才能被正确加载。因为config的相关配置会先于application.properties,而bootstrap.properties的加载也是先于application.properties。
  • 创建一个Rest Api来返回配置中心的from属性,具体如下:
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;

/**
 * Created by ding on 2018/5/21.
 */
@RefreshScope
@RestController
public class TestController {
    @Value("${from}")
    private String from;

    @RequestMapping("/from")
    public String from() {
        return this.from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getFrom() {
        return from;
    }
}

通过@Value("${from}")绑定配置服务中配置的from属性。

启动该应用,并访问:http://localhost:7002/from ,我们就可以根据配置内容输出对应环境的from内容了。

完整示例:spring-cloud-config-demo

说明:更改了git上配置文件的值后,微服务的客户端获取的配置文件的值是不会改变的,需要在微服务的客户端pom文件中的添加如下依赖:

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

当git上的值改为变后,需要通过post调用url:http://localhost:7002/refresh,如,当from的发生改变,则会返回:

[
    "config.client.version",
    "from"
]

然后再调用http://localhost:7002/from,则正在获取到最新的正确的值。

本文参考:http://blog.didispace.com/springcloud4/

相关文章

网友评论

    本文标题:Spring Cloud构建微服务架构--分布式配置中心

    本文链接:https://www.haomeiwen.com/subject/frwfjftx.html