[Spring Cloud] 2.Spring Cloud Native Application

Spring Cloud Native Application 原生应用

原生应用:是一种程序开发风格,是连续交付(持续集成)和值驱动领域的最佳实践。html

12-factors

与12-Factor (SaaS)应用,有着相似的目标: (12-Factor 为构建以下的 SaaS 应用提供了方法论):java

  • 使用标准化流程自动配置,从而使新的开发者花费最少的学习成本加入这个项目。
  • 和操做系统之间尽量的划清界限,在各个系统中提供最大的可移植性。
  • 适合部署在现代的云计算平台,从而在服务器和系统管理方面节省资源。
  • 将开发环境和生产环境的差别降至最低,并使用持续交付实施敏捷开发。
  • 能够在工具、架构和开发流程不发生明显变化的前提下实现扩展。

这套理论适用于任意语言和后端服务(数据库、消息队列、缓存等)开发的应用程序。正则表达式

12-factors 包含:spring

  • I. 基准代码 一份基准代码,多份部署
  • II. 依赖 显式声明依赖关系
  • III. 配置 按不一样的运行环境,对配置信息进行独立的存放 / 使用
  • IV. 后端服务 把后端服务看成附加资源
  • V. 构建,发布,运行 严格分离构建和运行
  • VI. 进程 以一个或多个无状态进程运行应用
  • VII. 端口绑定 经过端口绑定提供服务
  • VIII. 并发 经过进程模型进行扩展
  • IX. 易处理 快速启动和优雅终止可最大化健壮性
  • X. 开发环境与线上环境等价 尽量的保持开发,预发布,线上环境相同
  • XI. 日志 把日志看成事件流
  • XII. 管理进程 后台管理任务看成一次性进程运行

Spring Cloud 提供一种途径,使得可以方便快捷并按需的搭建一个可用的分布式应用。docker

在使用Spring Cloud 时不少特性是基于Spring Boot的, 另外还有两个库:Spring Cloud ContextSpring Cloud Commons数据库

Spring Cloud Context

提供一些工具,以及Spring Cloud应用(ApplicationContext)的基础服务。如:引导上下文;加解密;做用域重建;环境()bootstrap

Spring Cloud Commons

是一个不一样Spring Cloud实现的抽象层以及通用类集合。 如:Spring Cloud Netflix;Spring Cloud Consul后端


若是出现“Illegal key size”错误,那表示须要更新JCE策略文件,以得到更高的权限api


1 Spring Cloud Context: Application Context Services

Spring Boot 提供了一套固定的套路来使用spring构建应用,用一种约定俗成的方式来进行配置,并提供一套通用的管理、监控方式。 Spring Cloud 在此基础之上,增长一些能够按需配置的功能。缓存

1.1 The Bootstrap Application Context 引导上下文

一个Spring Cloud应用,首先会建立一个引导上下文来做为主应用上下文的父级。 负责从外部加载配置源。两个上下文共享一个Environment来作为Spring应用的外部配置源。

默认的引导属性拥有更高的优先级,所以,不能被本地配置所覆盖。

引导上下文使用了一个和Spring Boot主应用不一样的约定方式来加载配置。引导上下文使用bootstrap.yml(或者properties)来配置,经过这样很好的与主应用配置分离开来。

bootstrap.yml

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

引导上下文也能够经过在系统属性中配置:spring.cloud.bootstrap.enabled=false来关闭。

1.2 Application Context Hierarchies 应用上下文层级

若是使用 SpringApplication 或者 SpringApplicationBuilder 来构建上下文时,那么会添加一个 引导上下文(BootstrapContext)会做为父级上下文。

子级上下文会从父级上下文继承配置源以及配置文件,所以主应用会包含额外的配置来源。

额外的配置源包括:

  • "bootstrap":若是有任何非空PropertySourceLocators被发现,那会生成一个优先级更高的CompositePropertySource
  • "applicationConfig:[classpath:bootstrap.yml]":若是配置了bootstrap.ymlproperties,那么他们的配置项将被用于引导上下文(BootstrapContext),这样也会被子级上下文引用到。他们比application.yml的优先级低。

因为加载顺序使得bootstrap配置源会先被扫描,可是,注意:因为处于一个很是低的优先级,因此并无立刻加载bootstrap.yml中的数据,也正是这个缘由,一般被用来看成默认配置实用

能够设置父级上下文(ApplicationContext)来本身扩展上下文层级。 能够本身实现接口,也能够经过SpringApplicationBuilder提供的几个方便的工具方法(parent(),parent(),parent())。 不论自定义了多少上下文层级,bootstrap引导上下文都处于最高级。 在这个层级中的每个上下文都能访问到引导上下文的配置源,使用时须要注意避免无心的配置覆盖状况。 层级中的每个上下文原则上都应该有一个不一样的spring.application.name,所以当有配置服务器时,就会有一个不一样的远程配置源。

普通的上下文,有一个区分配置的规则:子级上下文中的属性会覆盖父级上下文中的属性,覆盖条件包含属性名和配置源名。也就是说能够对整个配置源进行覆盖。

注意:SpringApplicationBuilder容许在整个上下文层级中共享Environment,但此功能默认关闭。所以,当须要时,同级别的上下文不须要去包含同一个配置源,他们能够和父级上下文共享这些配置。


1.3 Changing the Location of Bootstrap Properties 改变引导上下文配置路径

能够经过配置spring.cloud.bootstrap.name来改变默认的引导上下文配置文件名。(默认值bootstrap)。

也能够经过配置spring.cloud.bootstrap.location来改变默认的引导上下文配置的扫描路径。(默认值

经过系统属性来改变以上两个配置项

配置文件中spring.config.*等配置项是被用于引导上下文的配置,并被加载到Environment中。

若是配置了spring.profiles.active或者经过Environment的api来指定一个特定配置项,那么这个特定配置文件也会被加载,就如同一个Spring Boot应用同样。

1.4 Overriding the Values of Remote Properties 覆盖远程配置项

被引导上下文加载的配置源一般都是一个远程的(例如:Config Server),默认状况下远程配置项不能被本地配置所覆盖。

若是应用想要覆盖远程配置项,则须要远程配置源经过配置spring.cloud.config.allowOverride=true来受权。一旦开启此功能,则能够在本地配置下面两个配置项来控制细节:

  • spring.cloud.config.overrideNone=true 覆盖本地全部配置源;
  • spring.cloud.config.overrideSystemProperties=false仅覆盖系统属性和环境变量,而不覆盖本地配置文件。

1.5 Customizing the Bootstrap Configuration 定制引导配置

能够在/META-INF/spring.factories中添加org.springframework.cloud.bootstrap.BootstrapConfiguration配置,来指定任何想要添加到引导上下文中的配置类(@Configuration),若是有多个能够用逗号分隔。任何想要在主应用中自动装配的spring bean 均可以经过这些配置类来定义。 配置类也能够是一个包含@BeansApplicationContextInitializer对象。 当配置类有必定依赖顺序时,能够经过@Order来指定顺序,默认:last


注意: 当使用自定义BootstrapConfiguration时,在主应用时要当心使用@ComponentScanned 防止没必要要的加载。最好使用一个特定的包名来放置那些自定义配置类,来避免与@ComponentScan,@SpringBootApplication重叠。


当引导处理结束时会自动注入到主应用的SpringApplication实例中。 在启动以前,引导上下文会找到spring.factories中的配置类以及全部被标记@BeansApplicationContextInitializer对象加入到主应用S上下文(SpringApplication

1.6 Customizing the Bootstrap Property Sources 定制引导上下文的配置源

默认状况下外部配置源是一个Config Server,固然也能够在spring.factories中配置PropertySourceLocator对象来手动添加外部配置源(其余Config Server;数据库等)

例如:

@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"));
    }

}

任何一个ApplicationContext都会创一个Environment对象,它包含了外部配置源。它也相似一个普通Spring Boot配置源,所以你能够经过它来定制本地配置项。(例如:spring.application.name

若是jar中包含上面代码中的class,而且在META-INF/spring.factories包含:

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

那么,这个自定义配置源将会在classpath下全部的应用中被使用。


1.7 Environment Changes 改变环境

应用会监听EnvironmentChangedEvent事件,能够经过ApplicationListeners来响应这个事件。

当配置项发生变更时,EnvironmentChangedEvent事件被抛出。 此时,应用会作出:

  • 重建上下文中全部的@ConfigurationProperties对象
  • 对全部的日志属性logging.level.*进行设定
  • 注意: Config Client默认不会主动去检测Environment的改变,不过能够经过一个定时任务(@Scheduled)去轮询。可是,一般来讲并不建议用这样的方式。最好,经过广播EnvironmentChangedEvent事件这种方式来处理。(例如使用:Spring Cloud Bus

因为EnvironmentChangedEvent事件是经过Spring标准API来完成的,这就致使当Environment发生改变时,会有大量的对象刷新。 例如:动态配置一个DataSource的链接池的maxPoolSize,当maxPoolSize发生改变时,致使整个ApplicationContext进入一个阻塞的重建@ConfigurationProperties阶段。 为了解决这个问题,须要使用@RefreshScope

1.8 Refresh Scope 刷新范围

能够在@Bean 上标记一个@Refresh Scope 来指定这个Bean须要在配置改变时刷新。

Refresh scope 对象都是延迟代理初始化的,调用方法获取值时都是从初始化值得缓存中获取的。从新初始化其实也就是初始化缓存。

RefreshScoperefreshAll()方法能够刷新所有目标缓存。refresh(String)方法能够指定名字的缓存。这个功能会经过/refresh暴露到外部(如:HTTP,JMX

注意: @RefreshScope工做于@Configuration类,这样就会致使一个特殊的状况:互相依赖的Bean也会被刷新重建,并从新注入,这样@Configuration也就被从新初始化


1.9 Encryption and Decryption 加解密

Spring Cloud 为Environment提供了一个本地解密属性的预处理过程。 此过程,会使用几个扩展配置:encrypt.* 这样就能够经过{cipher}*来使用加密数据了。

若是须要使用这个特性,那就须要引入Spring Security RSA 到classpath。

一样这也须要对JCE进行扩展。

1.10 Endpoints 入口

对于一个基于Spring Boot Actuator应用,Spring Cloud原生应用扩展几个管理入口:

  • /env(POST) : 用于 更新Environment;重建@ConfigurationProperties;日志级别
  • /refresh: 从新加载引导上下文;刷新@RefreshScope对象。
  • /restart:重启ApplicationContext,此功能默认不可用
  • /pause/resume : 调用 Lifecycle 方法 (至关于ApplicationContextstop()start()方法)

2 Spring Cloud Commons: Common Abstractions 共用抽象层

如服务发现,负载均衡,断路器等模式都是以一个共用抽象层提供给全部的Spring Cloud客户端独立使用。

2.1 Spring RestTemplate as a Load Balancer Client 负载均衡

RestTemplate可使用@LoadBalanced在对应的@Bean进行连带的配置,就能够作成负载均衡。

注意: 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;
    }
}

2.2 Multiple RestTemplate objects 多重RestTemplat

若是RestTemplate不想要负载均衡,那就建立一个普通RestTemplate正常注入就好了。 若是须要负载均衡,在建立@Bean时加上@LoadBalanced限定就行。

若是须要混用的话,能够参见下面的例子:

@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);
    }
}

使用@Primary限定,避免@Autowired混淆。 若是上面的代码在进行RestOperations操做时,出现java.lang.IllegalArgumentException异常,能够设置spring.aop.proxyTargetClass=true来解决。

2.3 Ignore Network Interfaces 忽略网络接口

有的时候须要忽略某个名字的网络接口,把他们排除在服务发现注册以外。(如:运行于Docker容器) 能够设置一组正则表达式来对接口名进行匹配,来进行忽略这些接口:

application.yml

spring:
  cloud:
    inetutils:
      ignoredInterfaces:
        - docker0
        - veth.*
相关文章
相关标签/搜索