[Spring Cloud] 2.Spring Cloud Native Application

Spring Cloud Native Application 原生应用

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

12-factors

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

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

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

12-factors 包含:

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

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

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

Spring Cloud Context

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

Spring Cloud Commons

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


如果出现“Illegal key size”错误,那表示需要更新JCE策略文件,以获得更高的权限


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.*

转载于:https://my.oschina.net/roccn/blog/702985

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值