从公众号转载,关注微信公众号掌握更多技术动态
---------------------------------------------------------------
随着服务节点增多优先级增高
1.配置简介
(1)静态配置和动态配置
①静态配置
-
环境相关:数据库连接/中间件等服务链接配置
-
安全配置:用户名,密码,令牌,许可证书等
②动态配置
-
应用配置:请求超时,线程池,队列,缓存,数据库连接池的容量,日志级别,限流熔断阈值,黑白名单
-
功能开关:蓝绿发布,灰度开关,降级开关,高可用开关,数据库迁移
-
业务配置:促销规则,利率等业务参数
(2)开关驱动开发
功能稳定后一定要去除开关逻辑。
2.配置中心简介
(1)配置中心的引入
随着业务的发展、微服务架构的升级,服务的数量、程序的配置日益增多(各种微服务、各种服务器地址、各种参数),传统的配置文件方式和数据库的方式已无法满足开发人员对配置管理的要求:
-
安全性:配置跟随源代码保存在代码库中,容易造成配置泄漏;
-
分散性:配置文件过于分散,难以管理。
-
回溯性:而且静态配置文件方式修改无法追溯,所以当配置进行修改之后,不容易形成记录,更无法追溯是谁修改的、修改时间是什么、修改前是什么内容。
-
时效性:修改配置,需要重启服务才能生效;
-
繁琐性:一项配置更改,需要人工修改每一个服务的配置文件
-
局限性:无法支持动态调整:例如日志开关、功能开关;无法动态切换不同环境
因此,我们需要配置中心来统一管理配置,把业务开发者从复杂以及繁琐的配置中解脱出来,只需专注于业务代码本身,从而能够显著提升开发以及运维效率。同时将配置和发布包解藕也进一步提升发布的成功率,并为运维的细力度管控、应急处理等提供强有力的支持。
(2)配置中心应该具备的特点
-
配置集中管理:解决传统的“配置文件过于分散”的问题。所有的配置都集中在配置中心这一个地方管理,不需要每一个项目都自带一个,这样极大的减轻了开发成本。
-
统一标准
-
配置与应用分离:解决传统的“配置文件无法区分环境”的问题,配置并不跟着环境走,当不同环境有不同需求的时候,就到配置中心获取即可,极大的减轻了运维部署成本。
-
实时更新:解决传统的“静态化配置”的问题。线上系统需要调整参数的时候,只需要在配置中心动态修改即可。
-
高性能、高可用性
-
读多写少;请求量多、高并发;
-
不同环境配置隔离(开发、测试、预发布、灰度/线上);
3.变更推送如何实现
配置信息存储之后,我们需要考虑如何将配置的变更推送给服务端,这样就可以实现配置的 动态变更,不需要重启服务器就能让配置生效了。而一般会有两种思路来实现变更推 送:一种是轮询查询的方式;一种是长连推送的方式。
轮询查询很简单,就是应用程序向配置中心客户端注册一个监听器,配置中心的客户端,定 期地(比如 1 分钟)查询所需要的配置是否有变化,如果有变化则通知触发监听器,让应用程序得到变更通知。 这里有一个需要注意的点,如果有很多应用服务器都去轮询拉取配置,由于返回的配置项可 能会很大,那么配置中心服务的带宽就会成为瓶颈。为了解决这个问题,会给配置中心 的每一个配置项,多存储一个根据配置项计算出来的 MD5 值。配置项一旦变化,这个 MD5 值也会随之改变。配置中心客户端在获取到配置的同时,也会 获取到配置的 MD5 值,并且存储起来。那么在轮询查询的时候,需要先确认存储的 MD5 值,和配置中心的 MD5 是不是一致的。如果不一致,这就说明配置中心中,存储的配置项 有变化,然后才会从配置中心拉取最新的配置。 由于配置中心里存储的配置项变化的几率不大,所以使用这种方式后,每次轮询请求就只是 返回一个 MD5 值,可以大大地减少配置中心服务器的带宽。
另一种长连的方式,则是在配置中心服务端保存每个连接关注的配置项列表。这样,当配置中心感知到配置变化后,就可以通过这个连接,把变更的配置推送给客户端。这种方式需要 保持长连,也需要保存连接和配置的对应关系,实现上要比轮询的方式复杂一些,但是相比 轮询方式来说,能够更加实时地获取配置变更的消息。
4.配置中心演进
(1)简版配置系统
设计说明点:
-
通过OA系统对每一条配置(每一个配置有唯一的配置ID)进行增删改查;
-
区分不同环境的配置,每个环境同一配置ID对应不同数据库记录;
-
配置最终以json格式(便于编辑和理解)储存在mysql数据库中;
-
引入redis集群,做配置的缓存(比如可以设置配置修改后1分钟后生效);
-
配置对外服务,多机器部署,满足性能需要;
-
如果有必要,可以引入配置历史修改记录;
很多时候,这样可以基本上满足我们对配置系统的基本需求,对配置的增删改查,能容忍一段时间的数据不一致性。这种设计,由于所有的配置都存放在集中式缓存中,这样集中式的缓存也会有他的性能瓶颈。而且,每次配置的访问都需要发起rpc请求(网络请求),因此考虑在客户端引入本地缓存(localCache,例如Ehcache)。
(2)配置中心之性能可用性改进
即使配置中心宕机,或者配置中心依赖的存储宕机,仍然能够保证应用程序是可以启动的。在客户端引入localcache,来解决系统的高可用,高性能、可伸缩性。相对于第一版的改进点是,在客户端引入localcache。开启线程异步调用配置服务,更新本地配置。这样可以减少rpc调用。基于数据的CAP原理,该方式只做到了AP,这里会存在数据的一段时间的不一致性,但最终会保证是配置的最终一致性。
localcache一般分为两级:第一级缓存是内存的缓存;另外一级缓 存是文件的缓存。 配置中心客户端在获取到 配置信息后,会同时把配置信息同步地写入到内存缓存,并且异步 地写入到文件缓存中。内存缓存的作用是降低客户端和配置中心的交互频率,提升配置获取 的性能;而文件的缓存的作用就是灾备,当应用程序重启时,一旦配置中心发生故障,那么 应用程序就会优先使用文件中的配置,这样虽然无法得到配置的变更消息(因为配置中心已 经宕机了),但是应用程序还是可以启动起来的,算是一种降级的方案。
(3)配置中心之数据一致性改进
还好,配置通常都只会有一个入口修改,因此可以考虑在配置修改后,通知应用服务清理本地缓存和分布式缓存。这里可以引入mq或ZooKeeper。
5.配置中心实践
(1)Apollo
①功能亮点
-
统一管理不同环境、不同集群的配置:Apollo 提供了一个统一界面,集中式管理不同环境、不同集群、不同命名空间的配置。同一份代码部署在不同的集群,可以有不同的配置,比如 zk 的地址等。通过命名空间可以很方便地支持多个不同应用共享同一份配置,同时还允许应用对共享的配置进行覆盖。
-
配置修改实时生效(热发布):用户在 Apollo 修改完配置并发布后,客户端能实时(1s)接收到最新的配置,并通知到应用程序。
-
版本发布管理:所有的配置发布都有版本概念,从而可以方便地支持配置的回滚。
-
灰度发布:支持配置的灰度发布,比如点击发布后,只对部分应用实例生效,等观察一段时间,确定没问题后再推给所有应用实例。
-
权限管理、发布审核、操作审计:应用和配置的管理都有完善的权限管理机制,对配置的管理还分为编辑和发布两个环节,从而减少人为的错误。所有的操作都有审计日志,方便追踪问题。
-
客户端配置信息监控:可以方便地看到配置被哪些实例使用。
-
提供 Java 和 .Net 原生客户端:
-
提供开放平台 API:Apollo 自身提供了比较完善的统一配置管理界面,支持多环境、多数据中心配置管理、权限、流程治理等特性。不过 Apollo 出于通用性考虑,对配置的修改不会做过多限制,只要符合基本的格式就能够保存。
-
部署简单:配置中心作为基础服务,对可用性要求非常高,这就需要 Apollo 对外部依赖尽可能地少。Apollo 还提供了打包脚本,一键就可以生成所有需要的安装包,并且支持自定义运行时的参数。
②核心概念
应用:应用就是项目,Apollo 客户端在运行时需要知道应用的标识,从而可以根据这个标识去配置中心获取对应的配置。Spring Boot中建议直接配置在application.properties 中。
环境:环境就是常见的开发、测试、生产等,不同的环境对应的配置内容不一样。Apollo 客户端在运行时除了需要知道项目当前的身份标识,还需要知道当前项目对应的环境,从而可以根据环境去配置中心获取对应的配置(/opt/settings/server/properties)。目前支持的环境有 Local(本地环境,加载本地配置)、DEV(开发环境)、FAT(测试环境)、UAT(集成环境)、PRO(生产环境)。
集群cluster:在多机房的环境下,针对不同的机房,可以划分出不同的集群,集群可以拥有不同的配置。(/opt/settings/server/properties)多版本也可以使用
命名空间namespace:命名空间可以用来对配置做分类,不同类型的配置存放在不同的命名空间中,如数据库配置文件、消息队列配置、业务相关的配置等。命名空间还有一个公共的特性,那就是让多个项目共用同一份配置,比如 Redis 集群配置。
权限控制:通过权限控制可以防止配置被不相干的人误操作。对于开发人员,可以只分配测试环境的修改权限和发布权限,只有负责人才能有正式环境的权限。
(2)Spring Cloud Config
和Spring是无缝集成,使用起来非常方便。并且它的配置存储支持Git,不过它没有可视化的操作界面,配置的生效也不是实时的,需要重启或去刷新。所以比较适用于小型项目快速上手。
Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。Spring cloud使用git或svn存放配置文件,默认情况下使用git。