使用Spring Cloud配置服务器控制你的配置

使用Spring Cloud配置服务器控制你的配置

摘要 本文是《Spring Microservices In Action》第三章关于配置管理的中文翻译,在微服务实践中将所有微服务的配置集中外置到配置中心统一管理,通过将配置管理抽象成独立的服务来简化在不同的环境中的微服务配置管理,帮助微服务无状态化和轻量部署以及调度,已经成为业内默认的最佳实践,Spring Cloud开放的子项目ConfigServer,阿里云免费开放的应用配置中心产品ACM都是这种最佳实践的具体体现。

spring_micro_in_action_0

Spring Microservices In Action

-- John Carnell

本章涵盖

  • 将服务的配置从代码中分离
  • 􏰀配置Spring Cloud Config Server
  • 集成Spring Boot微服务
  • 加密敏感的配置属性

无论如何,开发者被迫将代码中的配置信息从代码中分离出来。毕竟,自从上学以来,不应该将值硬编码到代码中就已经烙印在开发者的脑海中。许多开发人员在其应用程序中使用常量类文件,以便将所有配置集中在一个地方。将应用程序配置数据直接写在代码里的通常是有问题的,因为每次必须更改配置时,都必须重新编译和/或重新部署应用程序。为了避免这种情况,开发人员将从应用程序代码中完全分离出配置信息。这使得在不经过重新编译过程的情况下对配置进行变更变得很容易,但这也会带来复杂性,因为你现在有另一个需要与应用程序一起管理和部署的工件。

许多开发人员转向低级属性文件(或YAML,JSON或XML)来存储其配置信息。这个属性文件放在一个服务器上,通常包含数据库和中间件连接信息以及那些将驱动应用程序行为的应用程序的元数据。将应用程序配置分离到一个属性文件是很容易的,大多数开发者不再对他们的应用程序配置进行更多的操作,仅只是把他们作为应用程序的一部分放在源代码版本控制之下并作为应用程序的一部分来部署。

这种方法可能适用于少数应用程序,但在处理可能包含数百个基于云的微服务的应用程序,而每个微服务又可能有多个服务实例在运行时,这种方式会很快崩溃。

突然之间,配置管理成为了一个大问题,因为基于云的环境中的应用程序开发和运维团队必须与那些配置文件所在的鼠窝搏斗。基于云的微服务开发强调

  1. 将应用程序的配置与正在部署的实际代码完全分开
  2. 构建服务器和应用程序,以及在你的环境中不变的镜像(image)
  3. 通过环境变量或通过读取集中式存储库中的配置,在服务器启动时注入任何应用程序的配置信息

本章将向你介绍在基于云的微服务应用程序中管理应用程序配置数据所需的核心原则和模式。

3.1 管理配置(和复杂性)

管理应用程序配置对于在云中运行的微服务至关重要,因为微服务实例需要在最少的人为干预下快速启动,以应对应用程序的可扩展性挑战。而每当部署时需要人手动配置或介入时,都会出现配置漂移,意外停机和滞后时间。

让我们开始讨论应用程序配置管理,建立我们想要遵循的四个原则:

  1. 隔离 - 我们希望将服务配置信息与实际的部署完全分开。应用程序配置不应与物理服务实例一起部署。相反,应将配置信息作为环境变量传递给启动服务,或者在服务启动时从集中式配置存储库中读取。
  2. 抽象 - 将配置数据的访问抽象并封装在一个服务后面而不是直接访问配置数据的存储(从文件或者通过JDBC访问存储配置的数据库),让应用程序使用基于REST的JSON服务来检索配置数据。
  3. 集中 - 由于基于云的应用程序可能实际上具有数百个服务,因此减少用于保存配置信息的不同配置存储库的数量至关重要。将你的应用程序配置集中到尽可能少的配置存储库中。
  4. 硬化(Harden) - 因为你的应用程序配置信息与你部署的服务完全隔离并集中,因此无论你使用何种解决方案都可能实现高度可用和冗余,这一点至关重要。

要记住的关键之一是,当你将配置信息分离到实际代码之外时,你将创建一个需要进行管理和版本控制的外部依赖关系。我必须强调应用程序配置数据需要版本控制和跟踪,因为管理不善的应用程序配置是难以察觉的错误和意外中断的肥沃滋生地。

意外的复杂性

我亲身体验过没有管理应用程序配置数据策略的危险性。在财富500强金融服务公司工作期间,我被要求帮助将一个大的WebSphere升级项目带回到正轨。该公司在WebSphere上拥有超过120个应用程序,并且需要在整个应用程序环境达到供应商维护期限结束之前将其基础结构从WebSphere 6升级到WebSphere 7。

该项目已经进行了一年,仅部署了120个应用程序中的一个。这个项目花费了一百万美元的人力和硬件成本,而目前的进度轨迹显示还需要再过两年才能完成升级。
当我开始与应用程序团队合作时,我发现的一个(也是仅仅一个)主要问题是应用程序团队用在属性文件内管理其所有数据库的配置以及服务的端点信息。这些属性文件是手动管理的,不受源代码控制。随着120个应用程序分布在四个环境和每个应用程序的多个WebSphere节点上,这个配置文件的老鼠窝导致团队需要尝试迁移分布在运行的数百台服务器和应用程序的12,000个配置文件。 (是的,你正在读取这个数字是:12,000。)这些文件还只是用于应用程序的配置,甚至不包括应用程序服务器的配置。
我说服了项目发起人要花费两个月的时间将所有的应用程序信息整合到一个由20个配置文件组成的集中版本控制的配置库中。当我向框架团队询问有关12000个配置文件的情况时,团队的首席工程师说,他们最初是围绕一小组应用程序设计配置策略的。然而,构建和部署的Web应用程序的数量在五年内爆炸性增长,尽管他们乞求花钱和时间重新修改其配置管理方法,但他们的业务合作伙伴和IT领导者从未将其视为优先事项。
不花时间来弄清楚如何进行配置管理会产生真实(而且是代价昂贵的)的负面影响。

3.1.1你的配置管理体系结构

正如你在第二章中所记得的那样,加载微服务的配置管理发生在微服务的启动(Bootstrapping)阶段。提醒一下,图3.1显示了微服务的生命周期。

spring_micro_in_action_1

让我们来看看前面3.1节(隔离,抽象,集中和硬化)中我们所阐述的四个原则,看看这四个原则在启动时如何应用。图3.2更详细地介绍了启动过程,并展示了配置服务在这一步中如何扮演了一个至关重要的角色。

spring_micro_in_action_2

在图3.2中,你会看到几个活动正在发生:

  1. 当一个微服务实例启动时,它将调用一个(配置)服务端点来读取与它正在运行的环境匹配的特定的配置信息。配置管理的连接信息(连接凭证,服务端点等等)将在启动时传入微服务。
  2. 实际的配置将驻存在一个存储库中。根据配置库的实现,你可以选择使用不同的实现来保存配置数据。实现选项可以包括源代码管理下的文件,关系数据库或kv数据库。
  3. 应用程序配置数据的实际管理独立于应用程序的部署方式。通常通过构建和部署流(pipeline)来处理对配置的变更管理,其中可以使用版本信息对配置的变更进行标记,并通过不同的环境进行部署。
  4. 当进行配置管理变更时,必须通知使用该配置的那些应用服务,同时刷新应用程序配置数据的副本。

现在我们已经完成了概念架构,它阐明了配置管理模式的不同部分以及这些部分如何组合在一起。我们现在要继续研究不同的解决方案,然后来看一个具体的实现方案。

3.1.2 实现的选择

幸运的是,你可以选择大量经过实战检验的开源项目来实现配置管理解决方案。让我们来看几个可用的不同选择并进行比较。表3.1列出了这些选择。

项目名 描述 特征
Etcd 用Go编写的开源项目用于服务发现和键值管理。其分布式计算模型使用raft协议(https:// raft.github.io/) 非常快速和可扩展。分布式。命令行驱动。易于使用和设置。
Eureka 由Netflix研发。经过严苛的实战检验。用于服务发现和键值管理。 分布式键值存储。 灵活的。学习成本较高。开箱即用的动态刷新客户端。
Consul 由Hashicorp研发。类似于Etcd和Eureka的特性,但是为其分布式计算模型使用了不同的算法(SWIM 协议 https:// www.cs.cornell.edu/~asdas/research/ dsn02-swim.pdf)) 快。 提供原生的服务发现功能,可直接与DNS集成。不提供客户端动态刷新能力。
ZooKeeper 一个提供分布式锁功能的Apache项目。常常用作访问键值数据的配置管理解决方案。 最古老,最经过实战检验的解决方案。用起来最复杂。可以用于配置管理,但只有在你的架构中已经使用了ZooKeeper的情况下才应该考虑。
Spring Cloud configuration server 开源项目,提供了一个通用的配置管理解决方案,不同的后端。它可以将Git,Eureka和Consul作为后端整合 非分布式密钥/值存储。为Spring和非Spring服务提供紧密集成可以使用多个后端进行故事配置数据,包括共享文件系统Eureka,Consul和Git
ACM 阿里云开放的免费配置中心产品,专注于应用配置管理的一站式解决方案。 简单易用,特性丰富。经过阿里巴巴大规模生产验证。推送性能高。高可靠的SLA。

表3.1中的所有解决方案均可轻松用于构建配置管理解决方案。对于本章以及本书其余部分的示例,将使用Spring Cloud config server。我选择这个解决方案的原因有很多,其中包括:

  1. Spring Cloud配置服务器易于设置和使用。
  2. Spring Cloud配置与Spring Boot紧密集成。你可以使用几个简单易用的注解(annotation)来逐个使用你应用程序的所有配置数据。
  3. Spring Cloud配置服务器提供多个后端用于存储配置数据。如果你已经在使用Eureka和Consul等工具,则可以将其直接插入Spring Cloud配置服务器。
  4. 表3.1中的所有解决方案中,Spring Cloud配置服务器可以直接与Git源代码管理平台集成。 Spring Cloud配置与Git的集成消除了你的解决方案中的额外依赖性,并使你的应用程序配置数据的版本控制变得轻而易举。

其他工具(Etcd,Consul,Eureka)不提供任何种类的本地版本,如果你想要的话,你必须自己构建它。如果你已经使用Git,则使用Spring Cloud配置服务器是一个有吸引力的选择。

对于本章的其余部分,我们将:

  1. 建立一个Spring Cloud配置服务器,并演示两种不同的机制来提供应用程序配置数据 - 一个使用filesystem,另一个使用Git仓库
  2. 继续构建许可服务,从数据库中检索数据
  3. 将Spring Cloud配置服务勾连到你的许可服务中来提供应用程序配置数据

3.2 构建我们的Spring Cloud 配置服务器

Spring Cloud配置服务器是基于REST的应用程序,它建立在Spring Boot之上。它不是一个独立的服务器。相反,你可以选择将其嵌入到已有的Spring Boot应用程序中,或者启动一个新的Spring Boot项目。

你需要做的第一件事就是建立一个叫做confsvr的新项目目录。在consvr目录中,创建一个新的Maven文件,该文件将用于在你的Spring Cloud配置服务器上启动所需的JAR文件。我不会列全整个Maven文件,而是列出以下列表中的关键部分。

<?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.thoughtmechanix</groupId>
    <artifactId>configurationserver</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>Config Server</name>
    <description>Config Server demo project</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.4.RELEASE</version>
    </parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <start-class>com.thoughtmechanix.confsvr. ConfigServerApplication </start-class>
        <java.version>1.8</java.version>
        <docker.image.name>johncarnell/tmx-confsvr</docker.image.name>
        <docker.image.tag>chapter3</docker.image.tag>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
    </dependencies>
    <!--Docker build Config Not Displayed -->
</project>

在上面的Maven文件中,首先声明要用于你的微服务的Spring Boot的版本(版本1.4.4)。Maven定义的下一个重要部分是你要使用的Spring Cloud配置父BOM(物料清单)。 Spring Cloud是一个大量独立项目的集合,都随着他们自己的版本而滚动的。此父级BOM包含云项目中使用的所有第三方库和依赖项以及组成该版本的各个项目的版本号。在本例中,你使用的是Spring Cloud的Camden.SR5版本。通过使用BOM定义,你可以保证在Spring Cloud中使用子项目的兼容版本。这也意味着你不必为你的子依赖声明版本号。清单3.1中的其余部分处理声明你将在服务中使用的特定Spring Cloud依赖关系。第一个依赖项是所有Spring Cloud项目都使用的spring-cloud-starter-config依赖项。第二个依赖项是spring-cloud-config-server启动项目。这包含spring-cloud-config-server的核心库。

阅读原文

http://click.aliyun.com/m/38913/

本站公众号
   欢迎关注本站公众号,获取更多程序园信息
开发小院