学习
实践
活动
工具
TVP
写文章

微服务和application.properties说再见:SpringBoot如何加载远程配置

本文涉及的代码示例托管在github

https://github.com/CharlesMaster/EnvironmentPostProcessorDemo

https://github.com/CharlesMaster/PropertySourceLocatorDemo

背景

传统开发微服务开发中,我们通常是将系统的配置(数据库,缓存服务器)在application.properties中配置,但随着系统规模的扩大,项目成员增多,越来越多的人更改配置文件,开发、测试、生产环境分离,因配置产生的问题越来越多。

为了避免因配置文件的导致的问题产生,配置服务应运而生。在分布式系统中,配置中心是一个独立的服务部件,作用是专门为其他服务提供系统启动所需的配置信息,保证系统正确启动。

配置中心有哪些功能呢?

1.将配置统进行集中管理,提供一配置服务,开发、测试、生产环境均可直接从配置服务器中读取配置信息。大致就是,应用在启动后从配置服务器中获取配置信息,加入到环境中。这样所有的配置服务都可以进行集中管理。

2.追溯到配置变更的历史,诸如是谁在什么时候修改了哪些内容,根据这些信息进行配置回滚操作。

3.配置中心还能够增加权限管理,保证不同角色不同权限的人只能访问到可看的配置,防止重要线上配置信息的泄露。

4.基于配置中心的微服务非常适合多环境的打包,不用多次打包,而是一次打包。另外,其也是拥抱docker的,docker一次打包都得好几G,如果多套配置,那么就是多个docker镜像,极大浪费资源),基于配置中心的发布可以做到one jar,one docker,run everywhere。

案例

我们首先编写一个简单的springboot服务,对外提供接口访问内部配置文件。如下所示,我们提供了两个接口,分别访问我们application.properties的两个属性。

application.properties文件的内容如下:

和我们所期望的一样,我们访问http://localhost:8080/author和http://localhost:8080/city分别读取到了application.properties的内容

Spring boot中可以通过xml或者@ImportResource来引入本地的配置文件,且格式只能是 properties(或者 yaml)。

按照我们背景中所提的需求,我们需要通过远程配置中心替换掉application.properties的内容,用配置中心统一管理配置。那么该如何实现呢?笔者提供两个方案。

方案一 EnvironmentPostProcessor

EnvironmentPostProcessor接口官网是这么描述的

Allows for customization of the application's {@link Environment} prior to the application context being refreshed.

EnvironmentPostProcessor implementations have to be registered in

META-INF/spring.factories, using the fully qualified name of this class as the key.

EnvironmentPostProcessor processors are encouraged to detect whether Spring's

org.springframework.core.Ordered Ordered interface has been implemented or if the @org.springframework.core.annotation.Order Order annotation is present and to sort instances accordingly if so prior to invocation.

那我们就按照这份文档进行改造。

classpath定义一个META-INF文件夹然后在其下面先建spring.factories文件,在其中指定:

这时我们将application.properties的author属性注释掉

再进行访问时http://localhost:8080/author页面时,返回值已经变为了我们注入的Jack

强调,MyEnvironmentPostProcessor并不会覆盖本地属性,比如不注释author=Charles仍然返回Charles而不是Jack,如果实际生产撰写此类中间件需要优化该代码进行去重工作,也可以增加远端覆盖本地、本地覆盖远端的功能点

方案二 PropertySourceLocator

该方案的思路来源于 Spring Cloud Config。我们先看怎么操作:

首先编写MyPropertySourceLocator。

接着让其生效

最后再创建 META-INFO/spring.factories

我们可以看到,和EnvironmentPostProcessor不一样的地方是,在application.properties仍然如下的情况下,

http://localhost:8080/author 返回了Tom,http://localhost:8080/city仍然是Hangzhou

走得更远

本文只是一个DEMO,如果想撰写这样的中间件产品或者spring boot starter,可以从以下方面考虑:

1.设置全局开关,支持读取配置中心打开还是关闭功能

2.配置中心的健康检查

3.基于微服务的规范性管理

4.远程和本地配置覆盖的功能

5.分布式系统中,服务启动时,如果启用了分布式配置中心,则将从配置中心获取的配置进行备份。配置中心失效时,使用备份的配置文件启动服务。

源码解析

本文讲实战,没有过多讲原理,关于PropertySourceLocator和Spring Cloud Config的源码解析,我会在下一篇文章中更新,请关注本公众号,这里剧透一下,Spring Cloud Config就是采用我们方案二的思路去做的。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180817G0SR3O00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

同媒体快讯

扫码关注腾讯云开发者

领取腾讯云代金券