SpringCloudConfig之服务端详解




写在前面

该文参考来自 程序猿DD 的Spring Cloud 微服务实战一书,该文是作为阅读了 spring cloud config 一章的读书笔记。书中版本比较老,我选择了最新稳定版的 spring cloud Greenwich.SR2 版本,该版本较书中版本有些变动。非常感谢作者提供了这么好的学习思路,谢谢!文章也参考了 Spring-cloud-config 的官方文档。


1. Environment 库

配置服务器的配置数据存储在哪里? 管理这种行为的策略是 EnvironmentRepository,它服务于Environment对象。该环境是从Spring环境(包括propertySources作为主要特性)复制域的浅版本。Environment 资源参数化有三个变量:

  • {application} 映射为客户端的 Spring.application.name
  • {profile} 映射为客户端的 spring.profiles.active (逗号分隔)
  • {label} 服务端特性,标记着一些列“版本控制” 文件

存储库实现的行为类似于 Spring boot 程序。从一个等于 spring.config.nmae{application} 参数,加载配置文件。spring.profiles.active 等于 {profiles} 参数。配置文件的优先规则也与常规 Spring boot 应用程序相同:active 配置优先于默认配置。如果有多个配置文件,则最后一个配置文件优先。


下面的示例是一个拥有引导配置的客户端程序:

bootstrap.yml.

spring:
  application:
    name: foo
  profiles:
    active: dev,mysql

在基于文件的存储库,服务端将从 application.yml (所有客户端共享的)和 foo.yml (foo.yml 优先) 创建一个 Environment 。你可以设置 spring.cloud.config.server.accept-empty 变为 false,这样如果没有找到应用程序,服务器将返回 HTTP 404状态。默认情况下,此标志设置为true。

1.1 Git 后端

前文创建的快速开始就是基于 Git 后端的,现在再来详细探讨下。

EnvironmentRepository 的默认实现使用 Git 后端,这对于管理升级和物理环境以及审计更改非常方便。要更改存储库的位置,可以设置服务端(例如application.yml)的spring.cloud.config.server.git.uri配置属性。如果您使用file:前缀设置它,那么它可以在本地存储库中工作,这样您就可以在没有服务器的情况下快速轻松地启动它。但是,在这种情况下,服务器直接操作本地存储库,而不进行克隆(从远程gitclone)。为了扩展配置服务器并使其具有高可用性,需要让服务器的所有实例都指向同一个存储库,这样只有共享的文件系统才能工作。即使在这种情况下,最好使用共享文件系统存储库的ssh:协议,以便服务器可以克隆它并使用本地工作副本作为缓存。

跳过 SSL 中心认证

在前一篇博文中,我们使用了 spring.cloud.config.server.git.skipSslValidation 属性,该属性是用于禁用配置服务器对 git 服务器的 SSL 证书的验证。

设置HTTP 连接超时

使用 spring.cloud.config.server.git.timeout属性, 配置服务器等待获取 HTTP 连接的时间(以秒为单位)。

模式匹配和多仓库

Spring Cloud 配置还支持对应用程序和配置文件名称进行模式匹配的更复杂需求。模式格式是一个逗号分隔的带有通配符的{application}/{profile}名称列表(注意,以通配符开头的模式可能需要加引号),如下面的示例所示:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          repos:
            simple: https://github.com/simple/config-repo
            special:
              pattern: special*/dev*,*special*/dev*
              uri: https://github.com/special/config-repo
            local:
              pattern: local*
              uri: file:/home/configsvc/config-repo

如果{application}/{profile}不匹配任何模式,它将使用spring.cloud.config.server.git.uri下定义的缺省URI。在上面的示例中,对于“simple”存储库,模式是simple/*(它只匹配所有配置文件中一个名为simple的应用程序)。local存储库匹配所有配置文件中以local开头的所有应用程序名称(/*后缀自动添加到没有配置文件匹配器的任何模式中)。


每个存储库还可以选择将配置文件存储在子目录中,搜索这些目录的模式可以指定为searchPaths。下面的例子展示了顶层的配置文件:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          searchPaths: foo,bar*

在前面的示例中,服务器在顶层和foo/子目录中搜索配置文件,以及名称以bar开头的任何子目录。

默认情况下,服务器在首次请求配置时克隆远程存储库。服务器可以配置为在启动时克隆存储库:

spring:
  cloud:
    config:
      server:
        git:
          clone-on-start: true

在配置服务器启动时设置要克隆的存储库有助于在配置服务器启动时快速识别配置错误的配置源。

Git 刷新速率

通过使用spring.cloud.config.server.git.refreshRate,可以控制配置服务器从Git后端获取更新配置数据的频率。此属性的值以秒为单位指定。默认值为0,这意味着每次请求配置服务器时,配置服务器都会从Git repo获取更新后的配置。


1.2 版本控制后端文件系统的使用

使用基于vcs(版本控制后端)的后端(gitsvn),文件被检出或克隆到本地文件系统。默认情况下,它们被放在系统临时目录中,前缀为config-repo-。例如,在linux上,它可以是/tmp/config-repo-<randomid>。一些操作系统经常清理临时目录。这可能导致意外的行为,比如丢失属性。为了避免这个问题,可以通过设置spring.cloud.config.server.git.basedirspring.cloud.config.server.svn.basedir来更改Config Server使用不驻留在系统临时结构中的目录。


1.3 文件系统后端

在配置服务端提供了一种从文件系统或者当前类路径下加载配置文件的方式,我们只需要配置 spring.profiles.active=native ,我们可以通过 spring.cloud.config.server.native.searchLocations 来指定具体的配置文件位置。

searchLocations 的默认值与本地Spring启动应用程序相同(即[classpath:/, classpath:/config, file:./,file:./config)。这不会公开application.properties。因为服务器中存在的任何属性源在发送到客户端之前都会被删除。


1.4 JDBC 后端

Spring Cloud Config Server支持JDBC(关系数据库)作为配置属性的后端。您可以通过向类路径添加spring-jdbc并使用jdbc配置文件或通过添加类型为JdbcEnvironmentRepository的bean来启用此功能。如果您在类路径中包含了正确的依赖项(有关详细信息,请参阅用户指南),Spring Boot将配置一个数据源。


数据库需要有一个名为PROPERTIES的表,其中的列称为APPLICATIONPROFILELABEL(与通常的环境含义相同),以及PROPERTIES风格的键和值对的keyvalue。在Java中,所有字段的类型都是String,因此您可以使它们成为任意长度的VARCHAR。属性值的行为与它们来自名为{application}-{profile}的Spring引导属性文件时的行为相同。属性,包括所有的加密和解密,它们将作为后处理步骤应用(也就是说,不是直接在存储库中实现)。


分析 JdbcEnvironmentRepository 类,发现其只有一个构造函数:

	public JdbcEnvironmentRepository(JdbcTemplate jdbc,
			JdbcEnvironmentProperties properties) {
		this.jdbc = jdbc;
		this.order = properties.getOrder();
		this.sql = properties.getSql();
	}

也就是说我们自己构造 JdbcEnvironmentRepository bean 的话,我们需要一个 JdbcEnvironmentProperties 对象,那么Spring cloud 是否有基于 jdbc 作为后端的自动呢?按以上的描述来看,确实有,并且我们只需要在类路径下添加spring-jdbc,即可启用自动配置。

通过 JdbcEnvironmentRepository 定位到源码,查看包的结构,找到 config (配置类一般都会在这里)。找到 JdbcRepositoryConfiguration

@Configuration
@Profile("jdbc")
@ConditionalOnClass(JdbcTemplate.class)
class JdbcRepositoryConfiguration {

	@Bean
	@ConditionalOnBean(JdbcTemplate.class)
	public JdbcEnvironmentRepository jdbcEnvironmentRepository(
			JdbcEnvironmentRepositoryFactory factory,
			JdbcEnvironmentProperties environmentProperties) {
		return factory.build(environmentProperties);
	}

}

以及它的工厂类:

	@Configuration
	@ConditionalOnClass(JdbcTemplate.class)
	static class JdbcFactoryConfig {

		@Bean
		@ConditionalOnBean(JdbcTemplate.class)
		public JdbcEnvironmentRepositoryFactory jdbcEnvironmentRepositoryFactory(
				JdbcTemplate jdbc) {
			return new JdbcEnvironmentRepositoryFactory(jdbc);
		}

	}

这证明上述的分析是正确的,JdbcTemplate 存在的情况下,我们无需手动创建 Bean,并且,我们可以通过 JdbcEnvironmentProperties 中声明的属性在配置文件中更改默认的配置(包括自定义如何从数据库中查询key-value对的sql语句)。

1.5 组合式后端

在某些场景中,您可能希望从多个环境存储库提取配置数据。为此,您可以在配置服务器的应用程序属性或YAML文件中启用组合配置文件。例如,如果希望从一个Subversion存储库和两个Git存储库中提取配置数据,可以为配置服务器设置以下属性:

spring:
  profiles:
    active: composite
  cloud:
    config:
      server:
        composite:
        -
          type: svn
          uri: file:///path/to/svn/repo
        -
          type: git
          uri: file:///path/to/rex/git/repo
        -
          type: git
          uri: file:///path/to/walter/git/repo

使用此配置,优先级由组合键下存储库的列出顺序决定。在上面的示例中,首先列出了Subversion存储库,因此在Subversion存储库中找到的值将覆盖其中一个Git存储库中为相同属性找到的值。在rex Git存储库中找到的值将先于在walter Git存储库中找到的相同属性的值。


如果只想从不同类型的存储库中提取配置数据,可以在配置服务器的应用程序属性或YAML文件中启用相应的配置文件,而不是复合配置文件。例如,如果希望从单个Git存储库和单个svn存储库提取配置数据,可以为配置服务器设置以下属性:

spring:
  profiles:
    active: git, vault
  cloud:
    config:
      server:
        git:
          uri: file:///path/to/git/repo
          order: 2
        svn:
          uri: file:///path/to/svn/repo
          order: 1

使用此配置,可以通过order属性确定优先级。可以使用order属性指定所有存储库的优先级顺序。阶属性的数值越低,优先级越高。存储库的优先级顺序有助于解决包含相同属性值的存储库之间的任何潜在冲突。


1.6 属性重载

配置服务器有一个 “overrides” 特性,允许操作员为所有应用程序提供配置属性。被覆盖的属性不能被应用程序使用普通的Spring引导挂钩意外地更改。要声明覆盖,请将名称-值对映射添加到spring.cloud.config.server.overrides,如下例所示:

spring:
  cloud:
    config:
      server:
        overrides:
          foo: bar

这将导致所有配置客户端应用程序读取foo=bar,独立于它们自己的配置。


2. 健康监测

配置服务器附带一个健康指示器,用于检查配置的环境存储库是否工作。默认情况下,它会向环境存储库请求一个名为app的应用程序、default profile 和默认label


您可以配置健康指示器来检查更多的应用程序以及自定义配置文件和自定义标签,如下面的示例所示:

spring:
  cloud:
    config:
      server:
        health:
          repositories:
            myservice:
              label: mylabel
            myservice-dev:
              name: myservice
              profiles: development

也可以通过 spring.cloud.config.server.health.enabled=false 来禁用健康监测。


3. 安全访问

您可以以任何对您有意义的方式保护您的配置服务器(从物理网络安全到OAuth2承载令牌),因为Spring securitySpring Boot为许多安全安排提供了支持。


要使用默认的Spring启动配置的HTTP基本安全性,请在类路径中包含Spring Security(例如,通过spring-boot-starter-security)。默认是user的用户名和随机生成的密码(这可以通过启动时的控制台日志查看)。随机密码在实践中并不有用,因此我们建议您配置密码(通过设置spring.security.user.password)并对其进行加密(有关如何进行加密的说明,请参阅下面的说明)。


有关加密和解密,我了解的并不多,留下文档地址

4. 高可用配置

spring cloud 实现服务端的高可用非常简单,主要有以下两种方式。

  • 传统模式:不需要为这些服务端做额外的配置,只需要遵守一个配置规则,将所有的 config server 都指向同一个 Git 仓库,这样所有的配置内容就通过统一的共享文件系统来维护。而客户端在指定 Config Server 位置时,只需要配置 Config Server 上层的负载均衡设备地址即可。
  • 服务模式:我们仍可以将 Config Server 作为一个普通的微服务应用,纳入 Eureka 的服务治理体系中。这样微服务应用就可以通过配置中心的服务名来获取配置信息。不过这部分实现需要客户端配合。

以上内容摘抄自 DD的 Spring Cloud 微服务实战一书

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值