林湾村龙猫:[简书地址] https://www.jianshu.com/p/edce8e8c139e
一, 前言
对于配置文件, 我们并不陌生, 它提供我们可以动态修改程序运行能力. 引用别人的一句话就是:
系统运行时 (runtime) 飞行姿态的动态调整!
我可以把我们的工作称之为在快速飞行的飞机上修理零件. 我们人类总是无法掌控和预知一切. 对于我们系统来说, 我们总是需要预留一些控制线条, 以便在我们需要的时候做出调整, 控制系统方向(如灰度控制, 限流调整), 这对于拥抱变化的互联网行业尤为重要.
对于单机版, 我们称之为配置(文件); 对于分布式集群系统, 我们称之为配置中心(系统);
二, 为什么要有分布式配置中心
1, 项目背景
我们现在有一个项目, 使用 SSM 进行开发的, 配置文件的话我们知道是一个叫做 application.properties 的文件.
# 业务参数相关配置
user.register.default.name = 小强
user.register.default.sex = 男
我们也知道这个配置文件会在项目启动的时候被加载到内存中进行使用的.
2, 需求一
由于业务的变动, 用户在以前进行注册的时候默认的用户名是 "小强", 但是新的领导来了, 需要把这个改成 "小明". 因为, 业务的流量还是比较大的, 所以, 没有办法在白天流量高峰期修改配置文件, 进行重启!
此时, 就辛苦开发的小哥了, 他们需要等到半夜里凌晨三四点的时候, 没有流量的时候, 小心翼翼的去修改 application.properties 配置文件, 必将系统进行重启.
另外, 公司采用的是集群, 进行了负载均衡, 系统部署在了多台服务器上, 那么开发小哥需要一台台的进行修改, 小心翼翼的进行修改, 生怕出了一点意外!
开发小哥是在忍受不了这种变更了, 修改一个配置就需要如此周折的去完成这件事情! 忍无可忍, 于是像交流群里的一位大神请教, 大神指点让他去搜索一下 "分布式配置中心".
3, 需求二
我们在进行业务开发的时候, 一般会有多个环境, 至少应该有三个: 开发, 测试, 线上. 那这三个环境之间的配置文件肯定是有不同的, 比如说他们之间的数据库是肯定不同的! application.properties 例如:
- # 数据库相关配置
- spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
- spring.datasource.driverClassName=com.MySQL.jdbc.Driver
- spring.datasource.url=jdbc:MySQL://192.168.1.128:3306/ufind
- spring.datasource.username=root
- spring.datasource.password=123456
那我们如何使不同环境之间进行隔离哪? 答案很简单, 不就是指定三个不同的文件, 然后在项目启动的时候指定不同的环境不就行了吗? 于是开发小哥就动起来了, 修改如下:
修改之后, 运维的小哥不愿意了! 因为, 一开始没有进行环境隔离的时候, 只有一个环境(开发完成之后, 直接修改配置文件, 合并到主干, 线上发布), 运维小哥在使用 Jenkins+Git+Maven 进行自动化集成的时候, 只需要配置一下就行了! 在 Jenkins 启动的脚本命令是: java -jar ssm.jar 就可以搞定了, 经开发小哥这样一搞, 修改启动的命令不说, 新增了环境, 还要为他们创建不同环境的自动化集成.
分别需要设置的命令如下:
java -jar -Dspring.profiles.active=dev nssas.jar
和
java -jar -Dspring.profiles.active=beta nssas.jar
和
java -jar -Dspring.profiles.active=prod nssas.jar
运维小哥的工作量直接翻了一倍多, 想想还有十几个项目需要这样进行修改, 运维小哥悄悄的拿起了抽屉里准备了很久的 xxx 走向了开发小哥.
4, 到底什么是分布式配置中心
从上边的两个小需求, 我们已经可以看出来, 传统配置的方式已经暴露出了很多问题, 其他的诸如: 历史版本管理, 权限控制, 安全性等等问题, 是传统的配置文件无法解决的!
随着业务的发展, 微服务架构的升级, 服务的数量, 程序的配置日益增多(各种微服务, 各种服务器地址, 各种参数), 传统的配置文件方式和数据库的方式已无法满足开发人员对配置管理的要求:
安全性: 配置跟随源代码保存在代码库中, 容易造成配置泄漏;
时效性: 修改配置, 需要重启服务才能生效;
局限性: 无法支持动态调整: 例如日志开关, 功能开关;
因此, 我们需要配置中心来统一管理配置! 把业务开发者从复杂以及繁琐的配置中解脱出来, 只需专注于业务代码本身, 从而能够显著提升开发以及运维效率. 同时将配置和发布包解藕也进一步提升发布的成功率, 并为运维的细力度管控, 应急处理等提供强有力的支持.
三, 配置的一步步演进
当我们是一个单机服务的是, 我们的配置通常写在一个文件中的, 代码发布的时候, 把配置文件和程序推送到机器上去.
1, 单机配置文件
当随着业务的用户量增加, 通常我们会把我们的服务进行多机器 (集群) 部署. 这时候, 配置的发布就变成了如下:
2, 多机器配置
行, 这样发配置也能接受, 业务的急剧扩张, 导致单机服务无法满业务需求. 这时候需要对单体大服务进行切开, 服务走向 SOA(微服务化).
3, 分布式集群部署配置文件
这样去部署配置简直是一场噩梦, 而且无法做到快速的动态的调整. 失去了配置主要意义之一. 这时候就需要今天说的统一配置中心.
三, 一个简版的配置中心是什么样的
1, 配置中心的特点
配置的增删改查;
不同环境配置隔离(开发, 测试, 预发布, 灰度 / 线上);
高性能, 高可用性;
请求量多, 高并发;
读多写少;
2, 简版配置系统
我们可以设计出如下的简版配置中心:
设计说明点:
通过 OA 系统对每一条配置 (每一个配置有唯一的配置 ID) 进行增删改查;
区分不同环境的配置, 每个环境同一配置 ID 对应不同数据库记录;
配置最终以 JSON 格式 (便于编辑和理解) 储存在 MySQL 数据库中;
引入 Redis 集群, 做配置的缓存(比如可以设置配置修改后 1 分钟后生效);
配置对外服务, 多机器部署, 满足性能需要;
如果有必要, 可以引入配置历史修改记录;
很多时候, 这样可以基本上满足我们对配置系统的基本需求, 对配置的增删改查, 能容忍一段时间的数据不一致性.
这种设计, 由于所有的配置都存放在集中式缓存中, 这样集中式的缓存也会有他的性能瓶颈. 而且, 每次配置的访问都需要发起 rpc 请求(网络请求), 因此考虑在客户端引入本地缓存(localCache, 例如 Ehcache).
四, 简版基础上的一些改进
1, 配置中心之性能可用性改进
考虑到, 减少网络请求的因素, 在客户端引入 localcache, 来解决系统的高可用, 高性能, 可伸缩性. 本地缓存配置中心如下:
相对于第一版的改进点是, 在客户端引入 localcache. 开启线程异步调用配置服务, 更新本地配置.
这样可以减少 rpc 调用.
基于数据的 CAP 原理, 该方式只做到了 AP, 这里会存在数据的一段时间的不一致性, 但最终会保证是配置的最终一致性. 如何解决这个数据不一致性问题?
2, 配置中心之数据一致性改进
还好, 配置通常都只会有一个入口修改, 因此可以考虑在配置修改后, 通知应用服务清理本地缓存和分布式缓存. 这里可以引入 mq 或 ZooKeeper.
最后通过, 推拉相结合的方式, 完成数据的一致性.
六, 开源项目
关于分布式配置中心, 网上已经有很多开源的解决方案, 例如:
1,Apollo
Apollo(阿波罗)是携程框架部门研发的分布式配置中心, 能够集中化管理应用不同环境, 不同集群的配置, 配置修改后能够实时推送到应用端, 并且具备规范的权限, 流程治理等特性, 适用于微服务配置管理场景.
项目地址: https://github.com/ctripcorp/apollo
2,XDiamond
全局配置中心, 存储应用的配置项, 解决配置混乱分散的问题. 名字来源于淘宝的开源项目 Diamond, 前面加上一个字母 X 以示区别.
项目地址: https://github.com/hengyunabc/xdiamond
3,Qconf
QConf 是一个分布式配置管理工具. 用来替代传统的配置文件, 使得配置信息和程序代码分离, 同时配置变化能够实时同步到客户端, 而且保证用户高效读取配置, 这使的工程师从琐碎的配置修改, 代码提交, 配置上线流程中解放出来, 极大地简化了配置管理工作.
项目地址: https://github.com/Qihoo360/QConf
4,Disconf
专注于各种「分布式系统配置管理」的「通用组件」和「通用平台」, 提供统一的「配置管理服务」包括 百度, 滴滴出行, 银联, 网易, 拉勾网, 苏宁易购, 顺丰科技 等知名互联网公司正在使用!「disconf」在「2015 年度新增开源软件排名 TOP 100(OSC 开源中国提供)」中排名第 16 强. Disconf 的功能特点描述图:
项目地址: https://github.com/knightliao/disconf
5,Spring Cloud Config
Spring Cloud Config 为分布式系统中的外部配置提供服务器和客户端支持.
项目地址:
6, 主要区别
参考文章:
- ,
- ,https://www.cnblogs.com/ASPNET2008/p/5166922.html
- ,
来源: https://www.cnblogs.com/xuliugen/p/10422330.html