如何分析SpringCloudConfig配置

今天给大家介绍一下如何分析Spring Cloud Config 配置。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。

成都创新互联公司专注于古雷港网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供古雷港营销型网站建设,古雷港网站制作、古雷港网页设计、古雷港网站官网定制、微信平台小程序开发服务,打造古雷港网络公司原创品牌,更为您提供古雷港网站排名全网营销落地服务。

 Spring Cloud Config Server 配置服务

Spring为扩展配置服务,提供了一个基于HTTP的资源绑定的api。(键值对,或者YAML内容) 此服务可以通过@EnableConfigServer非常容易的整合进Spring Boot应用中。

例如:ConfigServer.java

@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
  public static void main(String[] args) {
    SpringApplication.run(ConfigServer.class, args);
  }
}

默认情况下,和Spring Boot应用一样运行在8080端口,当然也有很多种方法修改此端口。最简单的方法,设置默认的配置资源库。 通过在jar中configserver.yml文件中配置spring.config.name=configserver;或者通过指定自己的configserver.yml

例如:application.properties

server.port: 8888
spring.cloud.config.server.git.uri: file://${user.home}/config-repo

${user.home}/config-repo,是一个git资源。内容为YAML或者properties文件内容。

例如:

$ cd $HOME
$ mkdir config-repo
$ cd config-repo
$ git init .
$ echo info.foo: bar > application.properties
$ git add -A .
$ git commit -m "Add application.properties"

注意:以上使用本地文件只是为了测试。生产中应该使用远程服务提供的配置资源。

1 Environment Repository 环境资源

在Config Server中,对于配置数据你想要怎么样存储呢?存储策略由Environment 中的EnvironmentRepository来决定。同时多个Environment之间也允许复制配置项,甚至配置源propertySources

Environment资源主要来自这三个参数:

  • {application}对应着客户端的spring.application.name配置;

  • {profile}对应着客户端spring.profiles.active配置;

  • {label}这是一个服务端功能,标记着配置文件的版本。

资源实例通常表现和Srping Boot应用加载配置文件类似:spring.config.name类似于{application}参数;spring.profiles.active类似于{profiles}参数。 对于特定配置文件的优先级也是类似Spring Boot的规则:特定的配置会覆盖默认配置,并且如果指定了多个,那最后一个优先级最高。

例如:一个客户端应用可以配置一下引导配置:

bootstrap.yml

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

普通Spring Boot应用也可以通过环境变量或者命令行方式配置以上信息

如果资源是基于文件方式的,那系统会从application.yml创建一个Environment共享给所有客户端,并且加载foo.yml进行覆盖。 如果YAML文件中有指定特定配置的话,那么这些特定配置比默认配置拥有着更高的优先级。 这些拥有更高优先级的配置文件在Environment之前,就逐个生成PropertySource并被加载。

1.1 Git Backend 基于GIT

默认情况下EnvironmentRepository是基于GIT的,这样非常方便管理更新、物理环境也方便对修改历史进行审计。 可以通过spring.cloud.config.server.git.uri配置属性修改Config Server的本地资源库(例如:在application.yml中修改)。 如果设置成file:前缀,那会从本地资源进行加载,这样方便你快速简易的启动服务。但是这样就是直接在本地资源库上进行操作,没有备份。(不过如果远程服务资源是不变得情况下,这种方式也无所谓。)

如果需要扩展Config Server使其具备高可用性,那你需要将所有的服务实例指向同一个资源,这样就工作在一个共享文件的环境下。在这个情况下最好使用ssh:协议去访问共享文件资源,这样可以备份资源同时可以使用本地缓存提高效率。

资源实例会把HTTP资源中的{label}映射成git标签(commit id, branch name 或者 tag) 如果git分支或者标签名上有斜杠"/"那映射成HTTP URL时会自动替换成"_"。使用括号、空格时需要小心。(例如使用cmd时需要加上双引号)

1.1.1 Placeholders in Git URI :git uri 中的占位符

当需要时,Spring Cloud Config Server 支持在GIT URI中使用{application}{profile}{label}三个占位符,但是要记住{label}总是会映射成git的标签。

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/myorg/{application}
1.1.2 Pattern Matching and Multiple Repositories 正则与多资源库

在应用配置文件与特定配置文件中可以同过正则表达式来支持更为复杂的情况。可以在{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。

上面例子中pattern属性是一个YAML数组,也可以使用YAML数组格式来定义。这样可以设置成多个配个配置文件。

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          repos:
            development:
              pattern:
                - */development
                - */staging
              uri: https://github.com/development/config-repo
            staging:
              pattern:
                - */qa
                - */production
              uri: https://github.com/staging/config-repo

每个资源库有一个可选的配置,用来指定扫描路径。

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

这样系统就会自动搜索foo的子目录,以及以bar开头的文件夹中的子目录。

默认情况下,当第一次请求配置时,系统复制远程资源库。系统也可以配置成一启动就复制远程资源库。

spring:
  cloud:
    config:
      server:
        git:
          uri: https://git/common/config-repo.git
          repos:
            team-a:
                pattern: team-a-*
                cloneOnStart: true
                uri: http://git/team-a/config-repo.git
            team-b:
                pattern: team-b-*
                cloneOnStart: false
                uri: http://git/team-b/config-repo.git
            team-c:
                pattern: team-c-*
                uri: http://git/team-a/config-repo.git

上面的例子中team-a的资源库会在启动时就从远程资源库进行复制,其他的则等到第一次请求时才从远程资源库复制。

如果远程资源库设置了权限认证,则可以如下配置:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          username: trolley
          password: strongpassword

如果你不是用HTTPS和用户认证,可以使用SSH uri 的格式。例如:git@github.com:configuration/cloud-configuration 这样你就需要先有SSH的key。 这种方式系统会使用JGit库进行访问,可以去查看相关文档。可以在~/.git/config中设置HTTPS代理配置,或者也可以通过JVM参数-Dhttps.proxyHost-Dhttps.proxyPort来配置代理。

提示: 当你不知道你的~/.git目录时,可以使用git config --global来指定。例如:git config --global http.sslVerify false

3.2.1.1.3 Placeholders in Git Search Paths : GIT路径搜索中的占位符

Spring Cloud 的 Config Server 也支持在搜索路径中使用{application}{profile}{label}占位符配置。例如:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
          searchPaths: '{application}'
1.2 File System Backend 基于文件系统

也有不使用git资源库的方式,那就是从本地classpath或者文件系统加载配置文件。这种方式可以通过spring.profiles.active=native开启。

使用file:前缀加载文件系统,否则从classpath中加载,也可以使用${}样式的环境占位符。例如:file:///${user.home}/config-repo

searchLocations默认值与本地Spring Boot应用的扫描路径一样,都是:[classpath:/, classpath:/config, file:./, file:./config] 这样并不用担心application.properties文件暴露给所有客户端,因为在发送给客户端之前就会被清理掉。

基于文件系统的配置服务对于测试和快速练手来说是比较好的,如果用于生产环境,那就需要确保文件系统的可靠性,并允许共享访问。

路径搜索时能够包含{application}{profile}{label},这样方便你按照目录来管理你的配置文件。

如果在路径搜索时不使用占位符,那也会尝试自动的在HTTP资源中加上{label}后缀,那这样就会从不同的路径加载到。因此,在默认情况下不使用占位符等价于在每一个路径后添加了/{label}/。例如:file:/tmp/config 就等价于 file:/tmp/config,file:/tmp/config/{label}

1.3 Sharing Configuration With All Applications 应用共享配置

通过基于文件(svn,本地)资源,文件名为application*的资源将在所有的应用客户端中共享。(application.properties,application.yml,application-*.properties) 可以通过这种方式来定义一个全局的默认配置,如有必要应用可以使用应用指定配置对其进行覆盖。

1.4 Property Overrides 属性覆盖

Config Server 有一个属性覆盖的特性,允许操作者通过提供一个配置属性去覆盖所有应用中的配置。通过普通的Spring Boot钩子方式来实现,因此应用不需要什么改变。

声明覆盖仅仅需要在spring.cloud.config.server.overrides中配置一个键值对。例如:

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

这样会引起所有的应用客户端去读取foo=bar去覆盖自己的配置。(当然应用拿到新的数据后自己决定如何使用,因此,覆盖并不是强制的,客户端可以自定义拿到新数据后的行为)

提示: 使用文件方式时,Spring环境中的占位符${}可以用""对"$"转义,例如:\${app.foo:bar} 。当使用YAML时,YAML本身会处理,因此不需要转义。

2.2 Health Indicator 健康指示器

Config Server 通过一个健康指示器来检测配置的EnvironmentRepository是否正常工作。 默认情况下会向EnvironmentRepository询问一个名字为app的应用配置,EnvironmentRepository实例回应default配置。

可以通过配置让健康指示器一起去检查多个应用的多个配置。例如:

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

也可以通过配置spring.cloud.config.server.health.enabled=false去关闭此功能。

2.2 Security 安全

你可以按你自己的情况用任何方法对Config Server进行安全处理。(从物理网络安全到OAuth3授权token),不过通过Spring Security 结合Spring Boot能提供一种更好的方式。

使用Spring Boot默认的基于HTTP安全方式,仅仅需要引入Spring Security依赖。(如:可以通过spring-boot-starter-security

默认情况使用一个用户名和一个随机产生的密码,这种方式并不是很靠谱,因此,建议通过spring-boot-starter-security配置密码,并对其进行加密处理。

2.3 Encryption and Decryption 加解密

重要:要使用此特性,需要完全的JCE授权,方法参见前文

如果远程资源是一个经过加密的内容(以{cipher}开头),在发送给客户端之前会被解密。 这样,配置内容就不用明文存放了。 当直接去替换一个没有解密的值时,会被标记为"invalid"(无效的)。 这基本上可以大部分的杜绝密钥泄露的发生。例如:

application.yml

spring:
  datasource:
    username: dbuser
    password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'

如果使用配置文件则加密数据不要加上双引号。例如:

application.properties

spring.datasource.username: dbuser
spring.datasource.password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ

这样就可以安全共享此文件,同时可以保护密钥。

这个服务通过/encrypt/decrypt端点向外暴露。这样就可以用过POST方式向/encrypt提交加密后的数据。例如:

$ curl localhost:8888/encrypt -d mysecret
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda

反过来也行,通过/decrypt安全提交数据。(前提是已经在服务端配置了相应的解密KEY)

$ curl localhost:8888/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret

在提交之前,存放这些加密数据存在着潜在的不安全性。

/encrypt/decrypt 都接受一个路径/*/{name}/{profiles}用于分开控制每一个应用的密码。

注意:如果需要为每一个应用使用不同的密码,则需要一个@Bean产生一个TextEncryptorLocator对象来创建不同的密钥对,并给它们赋予一个名字。当然这是可选的,默认不需要这样(所有应用使用相同的密钥)

Spring 命令行客户端(Spring Cloud CLI)也可以使用加解密特性。例如:

$ spring encrypt mysecret --key foo
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
$ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
mysecret

可以使用@来指定一个路径,包含一个存放加解密key 的文件。例如:

$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...

2.4 Key Management 密钥管理

Config Server 可以使用对称/非对称加解密算法。使用非对称算法拥有更好的安全性,但是对称算法更方便。

配置对称算法的key,只需要设置encrypt.key就行了。(或者使用环境变量ENCRYPT_KEY

配置非对称算法key,你可以选择在encrypt.key中配置一个PEM编码的文本,也可以通过encrypt.keyStore.*配置使用一个密钥库。

encrypt.keyStore.*包括如下配置:

  • location 一个资源路径

  • password 密钥库密码

  • alias 被使用的密钥标识

通过公钥加密,私钥解密。因此,原则上可以在服务端只配置公钥。但是实践中可能很少这样做,密钥管理在全部客户端处理过程都会被包含,而不仅仅是服务端。不过从另一方面说,如果服务端 真的不安全,而且只有少数几个客户端需要加密处理,那这样配置也有一定的合理性。

 2.5 Creating a Key Store for Testing 创建一个密钥库用于测试

可以通过如下配置来创建一个用于测试的密钥库:

$ keytool -genkeypair -alias mytestkey -keyalg RSA \
  -dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" \
  -keypass changeme -keystore server.jks -storepass letmein

server.jks文件放入classspath,然后在application.yml中进行以下配置:

encrypt:
  keyStore:
    location: classpath:/server.jks
    password: letmein
    alias: mytestkey
    secret: changeme

2.6 Using Multiple Keys and Key Rotation 使用多重密钥以及密钥轮换

通过添加{cipher}前缀来表明使用加密数据,系统会在对密文进行Base64解码之前寻找{name:value}前缀信息。密钥通过TextEncryptorLocator(无论哪种)实例,最终使用TextEncryptor来完成加解密。 如果配置了密钥库(encrypt.keystore.location),那默认的执行器(locator)就会按照配置的alias去密钥库中查找相应的密钥。例如:

foo:
  bar: `{cipher}{key:testkey}...`

上例中执行器(locator)将会去查找一个叫做“testkey”的密钥。密钥库的密码可以通过{secret:…}来指定,但是如非必要一般不指定。如果想使用密钥库密码,那建议使用定制SecretLocator对其加密处理。

如果只是对很少的配置数据进行加密的话,密钥轮换基本上没有必要。 但是,偶还还是会有需求去修改密钥的场景。在这种情况下,所有的客户端都需要改变源配置文件(如:git)来使用新的{key:…},最好还要事先检查密钥库中的密钥。

提示: {name:value}也可以在/encrypt数据请求时使用。

2.7 Serving Encrypted Properties 提供加密属性

有的时候需要客户端对配置数进行解密,而不是在服务端解密。这种情况下,仍然可以通过/encrypt/decrypt端点访问。那就需要明确指定配置数据在服务端发出时不解密:spring.cloud.config.server.encrypt.enabled=false。如果不关系端点访问,那就既不要配置密钥也不要开启此配置。

以上就是如何分析Spring Cloud Config 配置的全部内容了,更多与如何分析Spring Cloud Config 配置相关的内容可以搜索创新互联之前的文章或者浏览下面的文章进行学习哈!相信小编会给大家增添更多知识,希望大家能够支持一下创新互联!


本文名称:如何分析SpringCloudConfig配置
路径分享:http://scyanting.com/article/jjcseo.html