《Spring Cloud微服务架构进阶》——2.2 Spring Cloud特性

举报
华章计算机 发表于 2019/06/02 23:43:49 2019/06/02
【摘要】 本书摘自《Spring Cloud微服务架构进阶》——书中的第2章,第2.2.1节作者是朱荣鑫、张天、黄迪璇。

2.2 Spring Cloud特性

云原生应用程序开发风格鼓励在持续交付和价值驱动开发上采取最佳的实践策略,Spring Cloud提供了多种方式来促进云原生开发风格。Spring Cloud提供了一系列组件,可以在分布式系统中直接使用,这些组件大大降低了分布式系统的搭建和开发难度。

这些组件大多数由Spring Boot提供,Spring Cloud在此基础上添加了分布式系统的相关特性。Spring Cloud依赖于Spring Cloud Context和Spring Cloud Commons两个公共库,其中Spring Cloud Context为Spring Cloud应用程序上下文(ApplicationContext)提供了大量的实用工具和特性服务,而Spring Cloud Common是针对不同的Spring Cloud实现(如Spring Cloud Netflix Eureka和Spring Cloud Consul两种不同的服务注册与发现实现)提供上层抽象和公共类。

接下来将从这两个库着手,对Spring Cloud的相关特性进行简要介绍。

2.2.1 Spring Cloud Context:应用上下文

使用过Spring Boot的读者都或多或少地了解如何使用Spring构建应用,比如,配置一般都需要放置在统一的位置,暴露用于管理的网络接口等。Spring Cloud在这些最佳实践之上提供了新的特性,来适配微服务架构下的运维环境。

 1. Bootstrap上下文

除了应用上下文配置(application.yml或者application.properties)之外,Spring Cloud 应用程序还额外提供与Bootstrap上下文配置相关的应用属性。Bootstrap上下文对于主程序来说是一个父级上下文,它支持从外部资源中加载配置文件,和解密本地外部配置文件中的属性。Bootstrap上下文和应用上下文将共享一个环境(Environment),这是所有Spring应用程序的外部属性来源。一般来讲,Bootstrap上下文中的属性优先级较高,所以它们不能被本地配置所覆盖。

Bootstrap上下文使用与主程序不同的规则来加载外部配置。因此bootstrap.yml用于为Bootstrap上下文加载外部配置,区别于应用上下文的application.yml或者application.properties。一个简单的bootstrap.yml的例子如下所示:

spring:

    application:

        name: my-application

    cloud:

        config:

            uri: ${CONFIG_SERVER:http://localhost:8080}

如果想要禁止Bootstrap引导过程,可以在bootstrap.yml中设置,如下所示:

spring:

    cloud:

        bootstrap:

            enabled: false

2.应用上下文层级

Spring的上下文有一个特性:子级上下文将从父级中继承属性源和配置文件。如果通过SpringApplication或者SpringApplicationBuilder来构建应用程序上下文,那么Bootstrap上下文将会成为该应用程序上下文的父级上下文。

在Bootstrap上下文中扫描到的非空的PropertySourceLocators会以高优先级添加到CompositePropertySource中。如果通过bootstrap.yml来配置Bootstrap上下文,且在设定好父级上下文的情况下,bootstrap.yml中的属性会添加到子级的上下文。它们的优先级低于application.yml和其他添加到子级中作为创建Spring Boot应用的属性源。

基于属性源的排序规则,Bootstrap上下文中的属性优先,但是需要注意这些属性并不包含任何来自bootstrap.yml的数据。bootstrap.yml中的属性具备非常低的优先级,因此可以作为默认值。

可以简单地将父级上下文设置为应用上下文来扩展上下文的层次结构。Bootstrap上下文将会是最高级别上下文的父级。每一个在层次结构中的上下文都有它自己的Bootstrap属性源(可能为空),来避免无意中将父级上下文中的属性传递到它的后代中。层次结构中的每一个上下文原则上应该拥有自己不同的spring.application.name,以便在有配置中心的时候也能有不同的远程属性源。来自子级上下文的属性可以覆盖父级中的具有相同名称和属性源名称的属性。

3.修改Bootstrap配置文件的位置

bootstrap.yml的位置可以通过在配置属性中设置spring.cloud.bootstrap.name(默认是bootstrap)或者spring.cloud.bootstrap.location来修改。

4.重载远程属性

通过Bootstrap上下文添加到应用程序的属性源通常是远程的,例如来自配置中心,通常本地的配置文件不能覆盖这些远程属性源。一般来说过,启动命令行参数的优先级高于远程配置,可以通过设定启动命令行参数的方式覆盖远程配置。

如果想使用应用程序的系统属性或者配置文件覆盖远程属性,那么远程属性源必须设置为spring.cloud.config.allowOverride=true(这个配置在本地设置不会生效)。在远程属性源中设定上述配置后,就可以通过更为细粒度的设置来控制远程属性是否能被重载,具体配置如下所示。

spring:

    cloud:

        config:

            overrideNone: true #本地属性覆盖所有的远程属性源

            overrideSystemProperties: false#仅覆盖远程属性源中的系统属性和环境变量

5.自定义Bootstrap配置

自定义Bootstrap配置过程与Spring Boot自动配置运行原理类似,具体操作是在/META-INF/spring.factories文件中添加org.springframework.cloud.bootstrap.BootstrapConfiguration配置项。配置项的值是一系列用来创建Context的@Configuration配置类,配置类之间以逗号分隔。这些类可以为应用上下文提供Bean实例,配置类可以通过标记@Order来控制Bean实例初始化序列。如下例所示,在引导过程中添加了一个LogAutoConfiguration的配置类,为应用程序添加日志相关的Bean实例:

org.springframework.cloud.bootstrap.BootstrapConfiguration=\

    com.demo.starter.config.LogAutoConfiguration

6.自定义Bootstrap属性源

默认的Bootstrap外部配置属性源是Spring Cloud Config Server,即使用配置中心加载外部属性。但是用户也可以通过将PropertySourceLocator类型的Bean实例添加到Bootstrap上下文(在spring.factories添加对应的配置类)来添加额外的属性来源。通过这种方法可以从不同的服务器或者数据库中加载额外的属性,如下所示:

@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参数用于创建应用上下文,它具有Spring Boot提供的属性源,可以使用它们来加载特定的属性源(例如重新设置spring.application.name)。可以在META-INF/spring.factories文件中添加如下记录来配置属性源:

org.springframework.cloud.bootstrap.BootstrapConfiguration=\

    sample.custom.CustomPropertySourceLocator

上述配置令应用程序可以使用CustomPropertySourceLocator作为其属性源。

7. Environment变化

Config Client应用程序会监听EnvironmentChangeEvent事件,当监听到一个EnvironmentChangeEvent时,它将持有一个被改变的键值对列表,应用程序使用这些值来:

重新绑定所有的@ConfigurationProperties的Bean实例,更新本地的配置属性。

为在logging.level.*的所有属性设置日志的等级。

一般来讲,Config Client默认不会使用轮询方法来监听Environment中的改变。在Spring Cloud中,Spring Cloud Config Server使用Spring Cloud Bus将EnvironmentChangeEvent广播到所有的Config Client中,通知它们Environment发生变化。

EnvironmentChangeEvent是一个事件类,用于在Environment发生修改时发布事件。开发者可以通过访问/configprops端点(常规的Spring Boot Actuator端点)来验证这些更改是否绑定到@ConfigurationProperties的Bean实例上。例如一个DataSource的最大连接数量在运行时被改变了(DataSource默认由Spring Boot创建,属于@ConfigurationProperties的Bean)并且动态增加容量,可以通过查看Config Client应用程序的/configprops端点来验证DataSource的最大连接池数量是否发生变化。

8.刷新范围

一个被标记为@RefreshScope的Spring Bean实例在配置发生变更时可以重新进行初始化,即动态刷新配置,这是为了解决状态Bean实例只能在初始化的时候才能进行属性注入的问题。

被@RefreshScope修饰的Bean实例是懒加载的,即当它们被使用的时候才会进行初始化(方法被调用的时候),想要在下次方法调用前强制重新初始化一个Bean实例,只需要将它的缓存失效即可。

RefreshScope是上下文中的一个Bean实例,它有一个公共方法refreshAll,该方法可以通过清除目标缓存来刷新作用域中的所有Bean实例。RefreshScope也有一个refresh方法来按照名字刷新单个Bean。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。