分布式配置中心 - 2. Spring Cloud Config评估

Spring Cloud Config架构图

Spring Cloud Config架构-Git配置

从上图可以看到,Spring Cloud Config(Git版)的架构还是非常简单的。简单的代价就是缺少可视化配置界面,无法实现灰度发布和自动回滚。要实现比较复杂和细粒度的权限控制也比较困难。
如果只使用Spring Cloud Config也没法实现配置自动刷新,还要依赖于Spring Cloud Bus。

技术资料

Spring-Cloud-Config-官方文档-server
Spring-Cloud-Config-官方文档-client
Spring-Cloud-Config-配置中心-git

对配置中心的期望

在具体评估技术之前,可以先列一下我们希望该技术能实现的目标,然后进行逐一确认是否能实现。
对于配置中心,我们的期望如下:

从代码和项目管理角度

  • 清晰地按项目划分配置
  • 可以将项目间共通的配置提取公共配置
  • 可以支持非Java应用获取配置

从信息安全角度

  • 生产和测试配置有分别的权限控制
  • 可以对生产的密码配置进行不可逆的加密

从版本管理角度

  • 可以支持多个不同分支同时并行开发
  • 支持自动化持续集成

从运维角度

  • 当配置修改后可以动态刷新更新配置
  • 部署上可以实现高可用,当一个节点崩溃时不影响正常使用。
  • 当配置中心不可用时,应用不会立刻崩溃
  • 有可视化的界面,方便维护

Spring Cloud Config各种特性的具体实现

按目录划分不同应用/不同环境/不同版本

可以通过search-path实现。下面是按目录划分应用的范例:

1
2
3
4
5
6
7
spring:
cloud:
config:
server:
git:
uri: http://gitlab.anxintrust.com/config/java-project-config.git
search-paths: '{application}'

共享公共配置

可以在根目录下建立common/application.yml文件实现

1
2
3
search-paths:
- '{application}'
- common

动态刷新

可以通过/actuator/refresh加上@RefreshScope注解实现。
这个时候专门的@Configuration配置类的好处就体现出来了。只要给配置类加上@RefreshScope就可以了。而如果使用@Value获取配置的话,就需要在所有用到配置的类上加注解了。

加密

通过JCE(Java Cryptography Extension)实现。具体可以参见:Encryption and Decryption

测试和生产使用不同的仓库

为了信息安全考虑,生产和测试可以通过使用不同的Eureka服务,注册到不同的仓库
Spring Cloud Config 部署架构

版本管理/多分支并行开发

多分支并行开发可以使用git的分支来实现。
假设有两个人分别在branch1和branch2上开发,而这两个分支可能会产生冲突。那么可以将配置的git项目建立分支,然后在客户端改为如下配置

1
2
3
4
cloud:
config:
uri: http://127.0.0.1:20001/
label: branch1

高可用

如果在client的配置里写死server,会导致两个副作用:

  • 当ip修改后所有配置都需要修改
  • 无法做到高可用
    所以配合Eureka,将多个config server注册到eureka server上。具体实现可以参见:
    配置中心Config和Eureka结合 · SpringCloud入门指南 · 看云
    即将client配置改为:
    1
    2
    3
    4
    5
    6
    7
    cloud:
    config:
    label: master
    fail-fast: true
    discovery:
    enabled: true
    service-id: cloud-config-server

支持非Java应用获取配置

非Java应用可以通过http://ip:port/{application}/{profile}/{label} 获取配置。例如:
http://127.0.0.1:20001/cloud-config-client-demo/dev/master

例如:
Node.js通过Sidecar获取Spring Cloud Config配置

常见问题

配置文件优先级

Spring Cloud Config的配置需要早于application.yml/application.properties加载。不然就会从默认的http://localhost:8888/获取配置。
所以需要将配置写在resources/bootstrap.yml文件里。

源代码阅读参考

为什么bootstrap会在application配置之前读取
Spring Cloud BootstrapApplicationListener

Spring容器的刷新过程
SpringBoot源码分析之Spring容器的refresh过程 | Format’s Notes

Spring Cloud的热更新机制
Spring Cloud 是如何实现热更新的 · ScienJus’s Blog

其他参考资料

spring cloud:config-server中@RefreshScope的”陷阱” - 菩提树下的杨过 - 博客园

https://www.cnblogs.com/yjmyzz/p/8085530.html

后记

原本想在评估完Spring Cloud Config之后开始研究和部署Apollo。但实际评估下来觉得对于我们目前的状况来说,Spring Cloud Config就已经足够了。
我们当前的情况:

  • 研发团队规模小
  • 微服务节点少
  • 配置更新频率低
  • 后端基本都是Java服务

Apollo和Nacos在以下几方面有优势:

  • 更好的管理配置UI
  • 多层级的权限控制
  • 团队开发语言多样
  • 配置更新频繁
  • 微服务节点多

有一篇Nacos社区committer写的评估比较文可以作为参考,相对比较中立(略偏向Nacos):架构设计之微服务配置中心选型

本文永久链接 [ https://galaxyyao.github.io/2019/03/29/分布式配置中心-2-Spring-Cloud-Config评估/ ]