一般服务器的应用都有以下几种类型,

其中当属业务部分最多也最繁杂。

当应用越来越庞大和复杂时,单机就肯定不能满足需求了,然后就要考虑分布式了,接下可能会应用不同的语言来开发应用。

比如 nginx 毫无疑问的是用的最多的反向代理组件,使用 OpenResty 便要用到 lua,再比如前端要 seo ,一个解决办法就是使用 nodejs,到了后端分布式,那就更繁多了,可能会需要把业务一个个拆分成不同的服务单独运行...

然后就发现散落一地的配置文件:***properties***、***yml***、***json*** …

为了解决这个问题,我们采取了这么一种模式,通过 etcd 我们的项目就是这样,来收集所有的配置,然后统一的写到一个文件中去,任何应用都来访问这一个文件来找到自己的配置并应用。

这很好的解决了配置散落的问题,可以集中管理了,但是又存在另一个问题,各种类型的配置在一个文件里看起来好乱,而且在初始化时必须要完成这个文件才能启动应用。

所以下一个解决方案便想到用一个配置中心来解决问题。

Spring Cloud Config 项目

提供 服务端 和 客户端 支持 集中式 管理分布式环境下的应用配置 基于 Spring 环境,无缝 与 Spring 应用集成 可用于 任何 语言开发的程序 默认实现基于 git 仓库,可以进行 版本管理 可替换 自定义实现

Spring Cloud Config Server 作为配置中心服务端

拉取配置时更新 git 仓库副本,保证是最新结果 支持数据结构丰富,yml, json, properties 等 配合 eureke 可实现服务发现,配合 cloud bus 可实现配置推送更新 配置存储基于 git 仓库,可进行版本管理 简单可靠,有丰富的配套方案

Spring Cloud Config Client 默认客户端实现

SpringBoot 项目不需要改动任何代码,加入一个启动配置文件指明使用 ConfigServer 上哪个配置文件即可 简单使用示例

新建一个 git 仓库,添加一个配置文件。例如想要一个 billing的服务,性质是开发,运行环境是测试环境。

那么就新建一个 testing 的分支,然后提交一个 billing-dev.properties 的文件

devMode = true spring.application.name = billing spring.jdbc.host = localhost spring.jdbc.port = 3306 spring.jdbc.user = root spring.jdbc.password = 123qwe loging.file = demo

然后新建一个标准 maven 项目

ConfigServer.java @ aliyunzixun@xxx.com class ConfigServer { public static void main(String[] args) { SpringApplication.run(ConfigServer.class, args); }} application.yml server: port: 8888spring: cloud: config: server: git: uri:https://git.coding.net/tiangao/demo-config-server.git clone-on-start: true pom.xml <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>spring-cloud-demo</artifactId> <groupId>xyz.stg.cloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>config-server</artifactId><parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.1.RELEASE</version> </parent> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-config-server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> <version>1.2.1.RELEASE</version> </dependency> </dependencies></project>

好了,配置中心已经可以启动了,配最简单的可以用浏览器来访问。

想要 json 格式的怎么办呢?

还有 yml, properties

OK, 就是这样简单。不过直接就能通过 url 得到,是不是有点不安全,这也不难,加上依赖。

java <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> 然后在 application.yml 配置用户名和密码,user 便是用户名。 security: user: password: db1ab002-1fba-476d-a421-22113355

再访问就能看到如下的效果

这是 ConfigSever 默认实现的基本的 HttpBasic 的认证。

服务端好了现在来看看 SpringBoot 客户端

只需要添加一个启动配置文件:

java cloud: config: uri: http://127.0.0.1:8888 profile: dev label: testing name: billing password: db1ab002-1fba-476d-a421-22113355 username: user

当启动时看到下面标示的内容是即表示加载成功。

简单示例就这样,下面便是 Config 的使用示意图。

呐,就是这样,所有的配置都通过仓库来管理,应用启动时访问配置中心能拿到自己的配置就OK,再接下来就是各自的事情了。

仓库也不仅仅只能用 git, 还有 svn 和本地目录可以选择

svn:///${user.home}/config-repo file://${user.home}/config-repo

从简单的示例里可以看出,我们只要提交一种格式的配置文件,通过不同的方式访问即可得到不同格式的配置文件,这在ConfigServer里是如何实现的呢?

先看一共有多少种访问方式 /{name}/{profiles:.*[^-].*} /{name}/{profiles}/{label:.*} /{name}-{profiles}.properties /{label}/{name} /{profiles}.properties /{name}-{profiles}.json /{label}/{name}-{profiles}.json

然后就能发现有这么一个类,里面有各种资源类型的转换操作。EnvironmentController 的所有方法如下所示:

原来内部只存在一种资源抽象,所有的资源对象都是由这种类型转换而来。

一个应用的配置只需要应用名、属性和标签就可以定位到。嗯,原来这么简单,那 EnvironmentReposiroty 又是哪里实现呢?

findOne 方式在 AbstractScmEnvironmentRepository 中可以找到。

java @Override public synchronized Environment findOne(String application, String profile, String label) { NativeEnvironmentRepository delegate = new NativeEnvironmentRepository( getEnvironment()); Locations locations = getLocations(application, profile, label); delegate.setSearchLocations(locations.getLocations()); Environment result = delegate.findOne(application, profile, ""); result.setVersion(locations.getVersion()); result.setLabel(label); return this.cleaner.clean(result, getWorkingDirectory().toURI().toString(), getUri()); }

这其中又由 SearcPathLocator 接口的 getLocations() 来实际加载内容,这个方法就由具体的实现类来完成。

Spring Cloud Config Server 内部除了 JGitEnvironmentRepository 实现外还有另外三种实现。

SvnKitEnvironmentRepository NativeEnvironmentRepository MultipleJGitEnvironmentRepository

见名知其意,分别是 svn 本地目录以及多 git 仓库的实现。

来到客户端这边,SpringBoot

项目只需要加载依赖就可以使用到远程配置,现有项目迁移过去也不用改动任何代码,感觉好神奇。

达到这样的效果依赖于 springMVC 的抽象以及 springboot 的自动配置类加载。

```java

@Configuration

public class ConfigClientAutoConfiguration {

@Beanpublic ConfigClientProperties configClientProperties( Environment environment, ApplicationContext context) {...}aliyunzixun@xxx.com ConfigServerHealthIndicator configServerHealthIndicator( ConfigServicePropertySourceLocator locator, ConfigClientHealthProperties properties, Environment environment) { return new ConfigServerHealthIndicator(locator, environment, properties);}...

}

**ConfigClientAutoConfiguration** 这个是 ConfigClient 的自动配置类,加载时触发新建一个 ConfigServicePropertySourceLocator 的 bean, java

@Order (0)

public class ConfigServicePropertySourceLocator

implements PropertySourceLocator {

private RestTemplate restTemplate;private ConfigClientProperties defaultProperties;aliyunzixun@xxx.com@Retryable(interceptor = "configServerRetryInterceptor")public org.springframework.core.env.PropertySource<?> locate( org.springframework.core.env.Environment environment) { ... // Try all the labels until one works for (String label : labels) { Environment result = getRemoteEnvironment(restTemplate, properties, label.trim(), state); ...

}

```

然后在 ApplicationContextInitializer 的 initialize 方法中被调用 locate 方法从 ConfigServer 拉取配置文件,注入到 ConfigurableEnvironment 中,

@ aliyunzixun@xxx.com(PropertySourceBootstrapProperties.class)public class PropertySourceBootstrapConfiguration implementsApplicationContextInitializer<ConfigurableApplicationContext>, Ordered { aliyunzixun@xxx.com void initialize(ConfigurableApplicationContext applicationContext) {...ConfigurableEnvironment environment = applicationContext.getEnvironment();for (PropertySourceLocator locator : this.propertySourceLocators) {PropertySource<?> source = null;source = locator.locate(environment);if (source == null) {continue;}...}...}}

接着才是应用的初始化过程。

从这个过程可以看到,其他任何应用需要使用 ConfigServer 时只需要在应用初始化之前通过 http 拉取到配置文件即可。

了解了大致原理,便可以看到集中式管理的优点。

没有记忆负担:大家都使用一个仓库保存所有配置文件,方便查看。

降低冲突沟通成本:开发新功能是凡是有配置变动均向仓库的提交,在合并后其他人碰到配置问题时也不用到处找人问,看看仓库历史就知道什么发生了变化。

方便测试:测试环境下,测试人员也不用老是问开发环境配置的问题了,所有配置一目了然,更改配置也有记录,有问题向开发反馈也能帮助快速定位问题范围。

方便管理: 在模拟环境和生产环境下,通过分支保护和权限管理管理线上配置文件,由运维人员来管理。

聊聊 Spring Cloud Config相关推荐

  1. 聊聊spring cloud gateway的GlobalFilter

    序 本文主要研究一下spring cloud gateway的GlobalFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0 ...

  2. 从架构演进的角度聊聊Spring Cloud都做了些什么?

    Spring Cloud作为一套微服务治理的框架,几乎考虑到了微服务治理的方方面面,之前也写过一些关于Spring Cloud文章,主要偏重各组件的使用,本次分享主要解答这两个问题:Spring Cl ...

  3. Spring Cloud(九)高可用的分布式配置中心 Spring Cloud Config 集成 Eureka 服务

    上一篇文章,讲了SpringCloudConfig 集成Git仓库,这一篇我们讲一下SpringCloudConfig 配和 Eureka 注册中心一起使用 在分布式系统中,由于服务数量巨多,为了方便 ...

  4. Spring Cloud(八)高可用的分布式配置中心 Spring Cloud Config

    在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件.在Spring Cloud中,有分布式配置中心组件spring cloud config,它支持配 ...

  5. spring cloud连载第二篇之Spring Cloud Config

    Spring Cloud Config Spring Cloud Config为分布式服务提供了服务侧和客户侧的外部配置支持.通过Spring Cloud Config你可以有一个统一的地方来管理所有 ...

  6. spring cloud config将配置存储在数据库中

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! Spring Cloud Config Server最常见是将配置文件放在本地或者远程Git仓库, ...

  7. java B2B2C Springcloud多租户电子商城系统-(七)高可用的分布式配置中心(Spring Cloud Config)...

    讲述了一个服务如何从配置中心读取文件,配置中心如何从远程git读取配置文件,当服务实例很多时,都从配置中心读取文件,这时可以考虑将配置中心做成一个微服务,将其集群化,从而达到高可用,架构图如下: 一. ...

  8. 企业分布式微服务云SpringCloud SpringBoot mybatis (七)高可用的分布式配置中心(Spring Cloud Config)...

    讲述了一个服务如何从配置中心读取文件,配置中心如何从远程git读取配置文件,当服务实例很多时,都从配置中心读取文件,这时可以考虑将配置中心做成一个微服务,将其集群化,从而达到高可用,架构图如下: 一. ...

  9. 为Spring Cloud Config Server配置远程git仓库

    简介 虽然在开发过程,在本地创建git仓库操作起来非常方便,但是在实际项目应用中,多个项目组需要通过一个中心服务器来共享配置,所以Spring Cloud配置中心支持远程git仓库,以使分散的项目组更 ...

最新文章

  1. 生活有时会有点苦涩——一位第六年还没发paper的PHD的自述
  2. mongodb查询数据库中某个字段中的值包含某个字符串的方法
  3. C语言实现hashset算法(附完整源码)
  4. Java即时编译:不仅仅是一个流行词
  5. numpy将所有数据变为0和1_Numpy库学习
  6. 多个excel文件内容合并到一个excel文件的多个sheet的小程序
  7. SpringBoot2.1.5(13)--- SpringBoot 特性下
  8. python查看dll中所有函数_Python中的函数
  9. 深度学习中的Precision和Recall,AP,mAP
  10. 使用CefSharp在.NET中嵌入Google kernel
  11. Stata Journal 2001-2019年全部期刊目录及下载链接
  12. 竞争对手强势、内忧仍存,小米如何守住智能家居高地?
  13. 华为nova10和荣耀70哪个值得买 哪个性能更好
  14. 中文分词jieba学习笔记
  15. 使用Python实现QQ窗口抖动
  16. css设置高度和宽度相同
  17. Google Earth揭密中国军事设施
  18. ​宝尊电商年亏2亿:阿里又成大股东 软银大幅减持
  19. 【总结】幂级数和泰勒级数
  20. cygwin php5.6,cygwin-autoconf环境搭建

热门文章

  1. Ubuntu下架设FTP服务器(转)
  2. ZABBIX 企业级分布式监控系统 1 监控系统简介
  3. 微信路况会不会超越地图导航?
  4. winform 安装部署
  5. 基于 MATLAB 的 PCM 编码解码实现
  6. tensorflow版本问题导致的错误AttributeError: module ‘tensorflow‘ has no attribute ‘***‘
  7. 基于opencv的霍夫方法和RANSAC方法两种圆检测
  8. c++ socket启动网卡接口
  9. VTK 7.0 安装中内存读取冲突 no override found for “.. 解决记录
  10. 对深拷贝与浅拷贝的再次理解