Spring Cloud

前言

由于想看一下spring cloud相关内容,因此翻译了一下 spring cloud文档,未完成部分会逐渐补上 转载请注明出处 http://blog.csdn.net/maozi_bsz

Spring Cloud

Spring cloud 提供了一些工具给开发者在分布式系统(例如 配置管理,服务发现,断路器,智能路由,微代理,控制总线)中来快速构建一些有着相同的工作模块。分布式系统衍生出一些模块,而使用 Spring cloud 的开发者可以快速的建立服务和应用,来实现这些模块。他们会在任何分布式环境中运行良好,包括开发者自己的笔记本电脑,数据中心和如 Cloud Foundry 的管理平台。

版本:Finchley.M2

Features

Spring Cloud 关注于为经典用例提供一个好的框架,并用扩展性覆盖其他用例。

  • 分布式的/版本控制的 配置
  • 服务的注册与发现
  • 路由
  • 服务到服务的调用
  • 负载均衡
  • 断路器
  • 分布式消息

Cloud Native Applications

Cloud Native 是一种开发模式它鼓励采用在连续和价值驱动开发中最好的实践。相关的学科是构建 12-factor Apps,它的开发实践由交付和操作目标来统一,例如使用声明式编程、管理和监控。Spring Cloud用具体几种方法推进这种开发方式,其起点就是一个功能集,包含了分布式系统的所有要么需要要么在需要时容易获取的组件。

大部分功能是由 Spring Boot 提供的,我们的 Spring Cloud 建立在其之上。一些是实现在 Spring Cloud 比如两个库:Spring Cloud Context 和 Spring Cloud Commons。Spring Cloud Context 提供一些工具和特殊的服务给 一个 Spring Cloud 应用的 ApplicationContext (bootstrap context, encryption, refresh scope and environment endpoints)。Spring Cloud Commons 是抽象和公共类的集合,它们被用在不同的 Spring Cloud 实现中(例如,Spring Cloud Netflix 和 Spring Cloud Consul)。

如果你遇到一个错误是由“Illegal key size”引起的,并且你在使用 Sun 公司的 JDK。那么你需要安装 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files。查看下列链接获取更多信息:

提取文件到 JDK/jre/lib/security 文件夹 (whichever version of JRE/JDK x64/x86 you are using).

Note,Spring Cloud 在无限制的 Apache 2.0 下发布。如果你想要贡献文档章节,或发现了一个错误,请在项目的 github 中查找源码或问题跟踪。

Spring Cloud Context: Application Context Services

Spring Boot有一个页面来展示如何用 Spring 构建项目:例如,他有常规配置文件的常规目录,以及用于常见管理和监视任务的端点。Spring Cloud 是建立在其之上的,并添加了一些所有组件在系统中可能或偶尔用到的功能。

The Bootstrap Application Context

一个 Spring Cloud 应用,通过创建一个 “bootstrap” 上下文来操作,它是 main application 的父上下文。其主要负责从外部源加载配置属性,也解码本地外部源的配置。这两个上下文共享 Environment ,它是每个 Spring 应用外部属性的源。Bootstrap 属性有着高优先级,因此默认情况下,他们不会被本地配置覆盖。

Bootstrap 上下文使用不同于主应用上下文的外部配置地址。因此,我们使用 bootstrap.yml 而不是 application.yml(or .properties)。来保证 bootstrap 和 主应用 很好的分离。

例如:

bootstrap.yml

spring:
  application:
    name: foo
  cloud:
    config:
      uri: ${SPRING_CONFIG_URI:http://localhost:8888}

如果你的应用需要特别的配置,那么设置 spring.application.name (在 bootstrap.ymlapplication.yml) 是个好办法。

你可以通过设置spring.cloud.bootstrap.enabled=false(例如在系统变量中)来禁止 bootstrap 进程完成

Application Context Hierarchies(层次结构)

如果你通过 SpringApplicationSpringApplicationBuilder 来创建应用上下文,那么 Bootstrap 上下文会被作为其父上下文添加。这是 Spring 的一个特性,子上下文会继承父上下文的属性与值,因此 “main” application的上下文会包含额外的属性,对比未使用 Spring Cloud Config的应用。额外的属性源如下:

  • “bootstrap”: 一个 CompositePropertySource 选项有较高的出现优先级,如果任何 PropertySourceLocators 属性在 Bootstrap context 中被找到并且他们有非空的属性。 一个使用 Spring Cloud Config Server 配置的例子。查看下文获取如何自定义 property source 内容的介绍。

  • “applicationConfig: [classpath:bootstrap.yml]” (and friends if Spring profiles are active). 如果你有一个 bootstrap.yml (或 properties) 那么这些属性会被用来配置 Bootstrap context ,当其父上下文被设置时,它们会被作为子上下文添加进去。它们比 application.yml (or properties) 和其他任何作为正常部分添加到 application 上下文的子上下文的优先级低。查看 下文 获取如何自定义这些 property sources 的介绍。

由于属性源的顺序,“bootstrap”是有优先级的。但是注意是不包括bootstrap.yml中的所有的数据,有一些有着很低的优先级,但是可以作为默认值设置。

你可以简单的设置父上下文为你创建的任何 ApplicationContext 来扩展层级结构,例如,使用其本身的接口,或使用 SpringApplicationBuilder 的快捷方法(parent(), child() and sibling())。bootstrap context 会是你创建上下文的最高级的父上下文。每个在层级中的上下文,会有它们自己的 “bootstrap” 属性源(也可能是空的)来避免不经意地将值传给后代。每个在层级中的上下文也(原则上)有一个不同的 spring.application.name,并且如果有 Config Server 会使用不同的远端属性源。常规的 Spring 上下文特性:来自子上下午的属性会覆盖父上下文的,通过名称和属性源名称(如果子上下文有一个属性源名称和父上下文相同,那么父上下文中的属性源,不会被包含到子上下文中)

注意,SpringApplicationBuilder 允许你在整个结构中分享 Environment ,但这不是默认的。因此,特别是兄弟关系上下文不需要具有相同的配置文件或属性源,即使它们将与父类共享共同的东西。

Changing the Location of Bootstrap Properties

bootstrap.yml(or .properties)的位置可以用 spring.cloud.bootstrap.name (默认 “bootstrap”)或 spring.cloud.bootstrap.location (默认为空)来指定。例如,在系统属性中。这些属性的行为类似于 spring.config.* 的变种。事实上,它们通常用来设置启动 ApplicationContext 通过在 Environment 中设置。如果激活 profile (通过 spring.profiles.active,或在你正在构建的context中使用 Environment API),profile中的属性就会被加载,就像正常的 spring 应用。例如 bootstrap-development.properties 用来给“开发” 配置。

Overriding the Values of Remote Properties

通过 bootstrap context 添加到你应用中的属性源,通常是远程的(例如 来自一个 Config Server),并且默认的,它们不会被本地的配置覆盖,除了在命令行中。如果你希望你的应用使用自己的系统属性或配置文件来重写远端属性,远端属性需要授予其权限通过 spring.cloud.config.allowOverride=true (在本地设置是无效的)。有一些细粒度的控制属性:
spring.cloud.config.overrideNone=true 可以被任何本地属性覆盖,和
spring.cloud.config.overrideSystemProperties=false 只有系统属性和环境变量应该可以覆盖,而不是本地文件。

Customizing the Bootstrap Configuration

Bootstrap 上下文可以被设置来做任何事,通过在 /META-INF/spring.factories 中的 org.springframework.cloud.bootstrap.BootstrapConfiguration 键下添加条目。这里有一个逗号分隔的 Spring @Configuration 类,将被用来创建上下文。任何你希望在 main application 上下文中出现可以自动注入的 bean,都可以写在这里,同样有一个特殊的 @Beans 的定义在类型 ApplicationContextInitializer。类可以标记 @Order 如果你希望控制它们启动的顺序(默认是 “last”)。

警告:请注意,你添加在 BootstrapConfiguration 的类没有用注解 @ComponentScanned 导入主应用上下文。对没用被 @ComponentScan@SpringBootApplication 声明覆盖的类,使用 boot 配置。

Bootstrap 过程,通过注入 initializers 到主 SpringApplication 实例(即,常规的 Spring Boot 启动序列,不管它是否独立运行或部署在应用服务)。首先 bootstrap 上下文从 spring.factories 找到的类中创建,然后所有 @Beans 注解的 ApplicationContextInitializer 类型会被添加到主 SpringApplication 在其启动前。

Customizing the Bootstrap Property Sources

默认的外部配置属性源,被 bootstrap 过程添加,其是 Config Server,但是你可以添加额外的源,通过添加 bean PropertySourceLocator 到 Bootstrap 上下文(通过 spring.factories)。你可以使用这些来添加额外的属性,来自一个不同的 Server,或 来自一个数据库,或来自一个实例。

自定义 locator 片段的示例:

@Configuration
public class CustomPropertySourceLocator implements PropertySourceLocator {

    @Override
    public PropertySource<?> locate(Environment environment) {
        return new MapPropertySource("customProperty",
                Collections.<String, Object>singletonMap("property.from.sample.custom.source", "worked as intended"));
    }

}

传进来的 Environment 是有关将要被创建的 ApplicationContext 的,就是,我们将要提供额外属性源的上下文。它早就有正常的 Spring Boot 属性源,因此你可以通过 Environment 来使用和定位一个属性(例如,通过 key spring.application.name,来获取默认 Config Server 中的值)。

如果你构建了一个jar,包含该类,并且将下面的配置添加到 META-INF/spring.factories 中:

org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator

然后 “customProperty” PropertySource 会在每个包含该 jar 的应用中出现。

Environment Changes

应用会监听 EnvironmentChangeEvent ,并且通过几个标准方式起作用(额外 ApplicationListeners 可以被作为 @Bean 添加)。当 EnvironmentChangeEvent 被观察到时,有一系列的 key 值被改变,然后应用会如下应用:

  • 重现绑定任何在上下文中 @ConfigurationProperties 注解的bean。
  • 设置新的 logger level 根据 logging.level.*

注意,默认情况下 Config Client 不会拉取 Environment 中的变化,并且一般情况下我们也不推荐监听变化(尽管你可以用 @Scheduled 注解开启)。如果你有横向的应用,那么最好广播 EnvironmentChangeEvent 到所有的实例,而不是它们各自去拉去(例如使用 Spring Cloud Bus)。

EnvironmentChangeEvent 包含了大量的类和刷新用例,只要你确实改变了 Environment 并发布事件(这些接口是公共的,并且是 Spring 核心的一部分)。 你可以通过 /configprops 端点来确认被 ConfigurationProperties 绑定的bean(常规的 Spring Boot Actuator 特性)。例如,被 DataSource 会有一个 maxPoolSize 属性在运行中改变(被 Spring Boot 创建的 DataSource 默认是一个 @ConfigurationProperties bean)并且容量是动态增长的。重新绑定 @ConfigurationProperties 不包含用例的另一个大类,类你需要更多的刷新控制和类你需要在整个 ApplicationContext 中原子化的改变。为了到达这个目的我们有 @RefreshScope

Refresh Scope

一个 Spring @Bean@RefreshScope 标记,在配置改变时,会被特殊对待。这解决了状态 bean,只有在初始化时才注入配置的问题。例如一个 DataSource 开启了一个链接当数据库 RUL 通过 Environment 变化时,我们可能希望这些连接的持有者能够完成他们正在做的事情。然后,下次有人从池中借用连接时,他会得到一个新URL的连接。

Refresh scope bean 是懒代理的,只当被使用时初始化(即,当一个方法被调用),目标行为作为缓存的初始值。要强制bean在下一个方法调用中重新初始化,只需使其缓存条目无效。

RefreshScope 是作为一个 bean 存在上下文中的,它有一个公共的方法 refreshAll() 来刷新所有目标 bean 通过清除它们的缓存。它也有一个方法 refresh(String) 来刷新单独的 bean ,通过名字。这些函数暴露在 /refresh 端点(通过 HTTP 或 JMX 访问)。

注意@RefreshScope 在一个 @Configuration 类上有效(技术上),但是它可能导致意外的行为:例如,它不意味着定义在类里的所有 @Beans 有它们自己的 @RefreshScope。具体来说,依赖于这些bean的任何东西都不能依赖于刷新启动时更新它们,除非它们自己在 @RefreshScope(这样他们会在刷新时重建并重新注入依赖,在这一点上,它们会用刷新过的 @Configuration 来重新初始化)。

Encryption and Decryption

Spring Cloud 有一个 Environment 预处理,来在本地解码属性值。它与 Config Server 使用相同的规则,并有相同的外部配置通过 encrypt.*。因此你可以用 {cipher}* 格式来编码值,然后直到有一个合理的key,然后它们会被解码病写入应用上下文的 Environment。为了在应用中使用编码特性,你需要包含 Spring Security RSA 到 classPath (Maven co-ordinates “org.springframework.security:spring-security-rsa”)并且你也需要添加全部的JCE到JVM。

如果你遇到一个错误是由“Illegal key size”引起的,并且你在使用 Sun 公司的 JDK。那么你需要安装 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files。查看下列链接获取更多信息:

提取文件到 JDK/jre/lib/security 文件夹 (whichever version of JRE/JDK x64/x86 you are using).

Endpoints

对于 Spring Boot Actuator 应用,这里有一些额外的管理端点:

  • POST 到 /env 来更新 Environment 并且重新绑定 @ConfigurationProperties 和日志等级
  • /refresh 来重新加载启动上下文并刷新 @RefreshScope bean
  • /restart 来关闭 ApplicationContext 并重启它(默认是禁用的)
  • /pause/resume 来调用 Lifecycle 方法(stop()start()ApplicationContext

Spring Cloud Commons: Common Abstractions

模式比如,服务发现,负载均衡,断路器都有相同的抽象层,可以被所有的 Spring Cloud 客户端使用,而不依赖于具体实现(例如 服务发现通过 Eureka 或 Consul).

@EnableDiscoveryClient

Commons 提供 @EnableDiscoveryClient 注解。这会寻找在 META-INF/spring.factories 中寻找 DiscoveryClient 的实现。Discovery Client 的实现会添加配置类到 spring.factoriesorg.springframework.cloud.client.discovery.EnableDiscoveryClient 键下。DiscoveryClient 的实现例子:是 Spring Cloud Netflix Eureka, Spring Cloud Consul DiscoverySpring Cloud Zookeeper Discovery

默认情况下,DiscoveryClient的实现会自动注册本地 Spring Boot 服务器到远程发现服务器。这可以通过设置 autoRegister=false@EnableDiscoveryClient 来禁止。

Health Indicator

Commons 创建一个 Spring Boot HealthIndicatorDiscoveryClient 可以参与,通过实现 DiscoveryHealthIndicator 接口。通过 HealthIndicator set spring.cloud.discovery.client.composite-indicator.enabled=false 可以禁止混用。一个基于 DiscoveryClient 通常的 HealthIndicator 是自动配置(DiscoveryClientHealthIndicator)。为了禁用它,可以设置 spring.cloud.discovery.client.health-indicator.enabled=false.。为了禁用 DiscoveryClientHealthIndicator 的描述域可以设置 spring.cloud.discovery.client.health-indicator.include-description=false ,不然 it can bubble up as the description of the rolled up HealthIndicator。

ServiceRegistry

Common 现在提供一个 ServiceRegistry 接口,来提供方法类似 register(Registration)deregister(Registration) 允许你提供自定义的注册服务。Registration 是一个标记接口。

@Configuration
@EnableDiscoveryClient(autoRegister=false)
public class MyConfiguration {
    private ServiceRegistry registry;

    public MyConfiguration(ServiceRegistry registry) {
        this.registry = registry;
    }

    // called via some external process, such as an event or a custom actuator endpoint
    public void register() {
        Registration registration = constructRegistration();
        this.registry.register(registration);
    }
}

每个 ServiceRegistry 实现,有它自己的 Registry 实现。

ServiceRegistry Auto-Registration

默认的,ServiceRegistry 的实现会自动注册运行的 service。有两种方法禁止自动注册。你可以设置 @EnableDiscoveryClient(autoRegister=false) 来永久的禁用自动注册。你可以设置 spring.cloud.service-registry.auto-registration.enabled=false 来通过配置禁止自动注册行为。

Service Registry Actuator Endpoint

一个 /service-registry actuator 端点被 Commons 提供。这个 endpoint 依托于一个 Registration bean 在 Spring Application Context。调用 /service-registry/instance-status 通过 GET 方法会返回 Registration 的状态。用 POST 方法调用相同的端点,并包含一个 String 的请求体 会改变当前的 Registration 的状态到新的值。请看 ServiceRegistry 文档,来查看可用的状态值和返回状态。

Spring RestTemplate as a Load Balancer Client

RestTemplate 可以自动的配置来使用 ribbon。为了创建一个负载均衡 RestTemplate 创建一个 RestTemplate @Bean 并且使用 @LoadBalanced qualifier()。

警告 一个RestTemplate不再通过自动配置创建。它必须被独立的应用创建。

@Configuration
public class MyConfiguration {

    @LoadBalanced
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

public class MyClass {
    @Autowired
    private RestTemplate restTemplate;

    public String doOtherStuff() {
        String results = restTemplate.getForObject("http://stores/stores", String.class);
        return results;
    }
}

其中 URI 需要使用虚拟主机名(即,service 名称,而不是一个主机名)。Ribbon 客户端被用来创建完整的物理地址。查看 RibbonAutoConfiguration 获取更多如何配置 RestTemplate 的细节。

Retrying Failed Requests

一个负载均衡 RestTemplate 可以被配置失败请求重试。默认的该逻辑是禁止的,你可以开启它通过添加 Spring Retry 到你应用的 classpath。关于失败请求重试,负载均衡 RestTemplate 会尊重一些 Ribbon 的配置值。如果你希望在 Spring Retry
存在于 classpath 时,禁用其逻辑你可以设置 spring.cloud.loadbalancer.retry.enabled=false。还有一些属性你可以使用 client.ribbon.MaxAutoRetriesclient.ribbon.MaxAutoRetriesNextServerclient.ribbon.OkToRetryOnAllOperations。查看 Ribbon documentation 来获取更多的关于属性的描述。

注意client 在下面例子中,应该替换为你自己的 Ribbon 客户端名称。

Multiple RestTemplate objects

如果你希望一个 RestTemplate 不是负载均衡的,创建一个 RestTemplate bean 并像常规 bean 一样注入。为了使用父在均衡,你需要在创建 RestTemplate bean 时使用 @LoadBalanced

重要,注意下面例子中常规 RestTemplate@Primary 注解,用来消除不合格的 @Autowired 注入。

@Configuration
public class MyConfiguration {

    @LoadBalanced
    @Bean
    RestTemplate loadBalanced() {
        return new RestTemplate();
    }

    @Primary
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

public class MyClass {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    @LoadBalanced
    private RestTemplate loadBalanced;

    public String doOtherStuff() {
        return loadBalanced.getForObject("http://stores/stores", String.class);
    }

    public String doStuff() {
        return restTemplate.getForObject("http://example.com", String.class);
    }
}

提示,如果你遇到像这样的错误 java.lang.IllegalArgumentException: Can not set org.springframework.web.client.RestTemplate field com.my.app.Foo.restTemplate to com.sun.proxy.$Proxy89 尝试注入 RestOperations 替代或设置 spring.aop.proxyTargetClass=true

Spring WebFlux WebClient as a Load Balancer Client

WebClient 可以通过配置使用 LoadBalancerClient。一个 LoadBalancerExchangeFilterFunction 会被自动配置,如果 spring-webflux 在 classpath 中。

@Configuration
public class MyConfiguration {

    @LoadBalanced
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

public class MyClass {
    @Autowired
    private LoadBalancerExchangeFilterFunction lbFunction;

    public Mono<String> doOtherStuff() {
        return WebClient.builder().baseUrl("http://stores")
            .filter(lbFunction)
            .build()
            .get()
            .uri("/stores")
            .retrieve()
            .bodyToMono(String.class);
    }
}

其中 URI 需要使用虚拟主机名(即,service 名称,而不是一个主机名)。LoadBalancerClient 被用来创建完整的物理地址。

Ignore Network Interfaces

在某些时候,忽略确定的网络接口名字是有用的,这样他们可以被从 Service Discovery 的注册中被排除(例如,运行在一个 Docker 容器中)。可以设置正则表达式的列表,这样所需的网络接口会被忽略。下述的配置会忽略 “docker0” 接口,和所有以 “veth” 开头的接口。

application.yml

spring:
  cloud:
    inetutils:
      ignoredInterfaces:
        - docker0
        - veth.*

你也可以强制只使用特定的网络地址使用正则表达式列表:

application.yml

spring:
  cloud:
    inetutils:
      preferredNetworks:
        - 192.168
        - 10.0

你也可以强制只使用本地地址。查看 Inet4Address.html.isSiteLocalAddress() 查看网站本地地址的细节。

application.yml

spring:
  cloud:
    inetutils:
      useOnlySiteLocalInterfaces: true
HTTP Client Factories

Spring Cloud Commons 提供 bean 来创建 Apache HTTP 客户端 (ApacheHttpClientFactory) 和 OK HTTP 客户端 (OkHttpClientFactory)。OkHttpClientFactory 只在 OK HTTP jar 存在于 classpath 时,才会创建。此外,Spring Cloud Commons 提供 bean 来创建 两种客户端的链接管理,ApacheHttpClientConnectionManagerFactory 为 Apache HTTP 客户端创建管理,OkHttpClientConnectionPoolFactory 为 OK HTTP 客户端创建管理。你可以为这些 bean 提供你自己的实现,如果你希望自定义 HTTP 客户端在下游项目中如何被创建。你也可以禁用这些 bean 创造,通过设置 spring.cloud.httpclientfactories.apache.enabledspring.cloud.httpclientfactories.ok.enabledfalse

Spring Cloud Config

Finchley.M2

Spring Cloud Config 提供了服务器和客户端的支持,来在分布式系统中外化配置。使用 Config Server 你有一个中心位置来管理在所有环境中应用的外部属性。客户度和服务端的 Spring EnvironmentPropertySource 的抽象概念相同,因此他们很适应 Spring 应用,但是可以用来创建任何语言的任何应用。当应用程序通过部署管道从开发到测试并进入生产时,您可以管理这些环境之间的配置,并确保应用在迁移时有他们运行所需的所有东西。默认的服务储存端实现使用 git,因此它很容易的来支持配置环境的标签版本,配置内容也可以被很多的工具访问管理。添加替代的实现是容易的,使用 Spring configuration 接入他们。

Quick Start

开启服务器:

$ cd spring-cloud-config-server
$ ../mvnw spring-boot:run

该服务是一个 Spring Boot 应用你可以在 IDE 中运行来代替,如果你喜欢(main class 是 ConfigServerApplication)。然后试运行一个客户端:

$ curl localhost:8888/foo/development
{"name":"foo","label":"master","propertySources":[
  {"name":"https://github.com/scratches/config-repo/foo-development.properties","source":{"bar":"spam"}},
  {"name":"https://github.com/scratches/config-repo/foo.properties","source":{"foo":"bar"}}
]}

默认的定位属性源的策略是克隆一个 git 仓库(在 spring.cloud.config.server.git.uri)并使用它来初始化一个小的 SpringApplication。mini-application的 Environment 被用来枚举属性源然后通过 JSON 端点发布他们。

HTTP 服务有下表的资源:

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

上述 “application” 会被作为 spring.config.name 注入到 SpringApplication(即,常规 Spring Boot app 的 “application”),“profile” 是一个激活简介(或一个逗号分隔的属性列表),“label” 是一个可选的 git 标签 (默认为 “master”)。

Spring Cloud Config Server 为远程客户端从 git 仓库(必须被提供的)拉取配置:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo
Client Side Usage

为了在应用中使用这些特性,只需要构建一个 Spring Boot 应用并依赖 spring-cloud-config-client (例如,查看 config-client 的测试用例,或例子应用)。最方便的方式来添加依赖是通过 Spring Boot starter 的 org.springframework.cloud:spring-cloud-starter-config。There is also a parent pom and BOM (spring-cloud-starter-parent) for Maven users and a Spring IO version management properties file for Gradle and Spring CLI users. Example Maven configuration:

pom.xml

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

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

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

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

   <!-- repositories also needed for snapshots and milestones -->

然后你可以创建一个标准的 Spring Boot 应用,就像这个简单的 HTTP 服务器:

@SpringBootApplication
@RestController
public class Application {

    @RequestMapping("/")
    public String home() {
        return "Hello World!";
    }

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

}

当其运行时,它会从默认的8888端口本地配置服务拉取外部配置。为了更改启动行为,你可以改变配置服务器的位置使用 bootstrap.properties (像 application.properties 但是处于应用上下文的 bootstrap 阶段),例如:

spring.cloud.config.uri: http://myconfigserver.com

bootstrap的属性,会显示在 /env 端点,作为一个高优先级的属性源,例如。

$ curl localhost:8080/env
{
  "profiles":[],
  "configService:https://github.com/spring-cloud-samples/config-repo/bar.properties":{"foo":"bar"},
  "servletContextInitParams":{},
  "systemProperties":{...},
  ...
}

(一个叫做 “configService:/” 的属性源,包含属性 “foo” 有值 “bar” 并且是最高优先级)。

注意,属性源的 URL 是 git 仓库的 URL 不是配置服务器的 URL。

Spring Cloud Config Server

该服务提供了一个 HTTP的,基于资源的 API 给外部配置(名值对,或相等的YAML内容)。该服务器很容易嵌入 Spring Boot 应用通过使用 @EnableConfigServer 注解。因此下面这个应用是配置服务器:

ConfigServer.java

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

像所有的 Spring Boot 应用,它默认运行在8080端口,但是你可以通过多种方法,将它转到传统的8888端口。最简单的是,也设置一个默认的配置库,但是使用 spring.config.name=configserver (有一个 configserver.yml 在 Config Server jar中)加载。另一个方法是使用你自己的 application.properties ,例如:

application.properties

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

${user.home}/config-repo 是一个 git 仓库包含 YAML 和 属性文件。

注意,在 Windows 中,你需要额外的 “/” 在文件的 URL 中,如果他是绝对路径并有驱动前缀 例如:file:///${user.home}/config-repo

提示,创建 git 仓库的示例:

$ 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"

警告,只应该在测试用,使用本地的文件系统,作为 git 仓库。在生产环境中,使用一个服务器来作为 git 仓库放置配置属性。

警告,如果只保留文本文件,配置存储库的初始克隆将快速高效。如果您开始存储二进制文件,尤其是大型文件,您可能会遇到第一个配置请求的延迟和/或内存溢出错误。

Environment Repository

你希望在哪里为 Config Server 储存配置数据?控制这种行为的策略是 EnvironmentRepository,提供 Environment 对象。该 Environment 是来自 Spring Environment 的域的浅拷贝(包括 propertySources 作为主要特性)。Environment 被三个变量参数化:

  • {application} 映射到 “spring.application.name” 在客户端
  • {profile} 映射到 “spring.profiles.active” 在客户端(逗号分隔的列表)
  • {label} 是一个服务器端的特性,标记一个配置文件的 “versioned” 集合

仓库就像一个 Spring Boot 应用那样,实现了一般行为,加载配置文件,“spring.config.name” 等于 {application} 参数,“spring.profiles.active” 等于 {profiles} 参数。配置文件的优先级规则也与常规的 Boot 应用程序相同:主动配置文件优先于默认值,如果有多个配置文件,最后一个将获胜(就像往一个 Map 中添加条目)。

例如:一个客户端应用,有这样的 bootstrap 配置:

bootstrap.yml

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

(就像通常的 Spring Boot 应用,这些属性可以被设置为环境变量或命令行参数)。

如果配置是基于文件的,服务器会从 application.yml (被所有客户端共享) 和 foo.yml (有foo.yml优先考虑) 中创建一个 Environment 。如果YAML文件有内部有文档指向 Spring profies,这些会作为较高的优先级来提供(在 profiles 列表中的顺序),并且如果有 prfile-specific YAML(或 properties)文件,它们也会以更高的优先级提供,比默认优先级。高优先级更早的传输一个 PropertySource 列表给 Environment。(独立的 Spring Boot 应用中,也有类似的规则)

Git Backend

默认的 EnvironmentRepository 实现,使用 git 后台,git 后台对管理升级和物理环境非常方便,对审计更改也非常方便。为了改变仓库的位置,你可以在 Config Server 的配置属性中设置 “spring.cloud.config.server.git.uri”(例如,在 application.yml 中)。如果你设置了 file: 前缀,他应该作为一个本地仓库工作因此你可以快速开始而不需要服务器,但是这种情况下,服务器会直接在本地库操作,而不克隆他(如果它不是空的,这并不重要,因为 Config Server 从不更改“远程”库)。为了放大 Config Server 使其有高可用性,您需要使服务器的所有实例指向同一个存储库,因此只有一个共享文件系统才行。甚至在这种情况下最好使用 ssh:共享文件系统存储库的协议,以便服务器能够克隆它并使用本地工作副本作为缓存。

这个库实现映射 {label} 参数到 HTTP 资源,它是一个 git label (commit id,branch name 或 tag)。如果 git branch 或 tag name 包含了斜线(”/”)那么 label 在 HTTP URL 中应该使用 “(_)”代替(来避免与其它 URL 产生歧义)。例如,一个 label 是 foo/bar,替换斜杠后应该像这样 foo(_)bar。在 URL 中使用括号是要小心,如果你使用一个命令行客户端像 curl (例如,使用引号 ” 将它们转义)。

Placeholders in Git URI

Spring Cloud Config Server 支持一个 git 仓库地址有占位符 {application}profile (和 label 如果你需要它,但是记住它是 git 标签)。因此你可以简单的支持 “每个应用一个仓库” 的策略(例如):

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/myorg/{application}

或者一个 “每个 profile 一个仓库”的策略,有相同的模式但是使用 {profile}

Pattern Matching and Multiple Repositories

其也支持更复杂的需求,通过模式匹配在 application 和 profile 名称。这正则格式是逗号分隔的关于 {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} 没找到任何匹配,它会使用默认 URI 定义在 “spring.cloud.config.server.git.uri”。在上面的例子中,“simple” 仓库的正则是 simple/*(即,他只匹配应用名称“simple”,不管 profiles)。 “local” 仓库匹配所有的以“local”开头的应用名称和所有的 profiles(/* 后缀是自动添加的,如果正则中没有 profile 的匹配)。

注意,在上面例子中 “simple” 的 “一行”简写,只能被用在 URI 只有其属性设置时。如果需要设置其它东西(证书,正则等)你需要使用全格式。

pattern 属性在 repo 中,其实是一个列表,因此你可以使用 YAML 数组(或 0,1,等后缀在 properties 文件中)来绑定多个正则。你需要这样做,如果你将要运行一个有多个 profiles 的应用。例子:

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 将会猜测一个正则包含 profile 不以 * 结尾,暗示你真正想匹配的是一个系列profiles,以正则开头(因此 */staging 是一个简写对于 ["*/staging", "*/staging,*"])。例如,如果你需要一个应用本地在运行 “development” profile 但是 远程使用 “cloud” profile,是相同的。

每个库还可以选择存储配置文件的子目录,并正则搜索这些目录可以被指定为 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:
          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 的 config-repo 仓库在启动时,在所有请求之前。其他的仓库在进行配置请求之前,不会被克隆。

注意,设置存储库进行克隆在 Config Server 启动时可以在 Config Server 启动时很快帮助确定一个错误配置的源(例如,一个无效的库URI)。对一个配置源禁用 cloneOnStart ,Config Server 可能成功启动在存在配置错误或无效配置源的时候,直到应用从这些配置源中请求配置时,才会发现错误。

Authentication

为了使用基于 HTTP 的仓库权鉴,分别添加 “username” 和 “password” 到配置文件(不是 URL 中)。例如:

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

转载请注明出处 http://blog.csdn.net/maozi_bsz


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值