微服务 - 常见配置中心工作原理
一、配置中心基础
1.1 为什么要用配置中心?
配置实时生效:传统的静态配置方式要想修改某个配置只能修改之后重新发布应用,要实现动态性,可以选择使用数据库,通过定时轮询访问数据库来感知配置的变化。轮询频率低感知配置变化的延时就长,轮询频率高,感知配置变化的延时就短,但比较损耗性能,需要在实时性和性能之间做折中。配置中心专门针对这个业务场景,兼顾实时性和一致性来管理动态配置;
配置管理流程:配置的权限管控、灰度发布、版本管理、格式检验和安全配置等一系列的配置管理相关的特性,也是配置中心不可获取的一部分;
分布式场景:随着采用分布式的开发模式,项目之间的相互引用随着服务的不断增多,相互之间的调用复杂度成指数升高,每次投产或者上线新的项目时苦不堪言,需要引用配置中心治理。
1.2 配置中心支持功能
灰度发布:配置的灰度发布是配置中心比较重要的功能,当配置的变更影响比较大的时候,需要先在部分应用实例中验证配置的变更是否符合预期,然后再推送到所有应用实例。
权限管理:配置的变更和代码变更都是对应用运行逻辑的改变,重要的配置变更常常会带来核弹的效果,对于配置变更的权限管控和审计能力同样是配置中心重要的功能。
版本管理 &回滚:当配置变更不符合预期的时候,需要根据配置的发布版本进行回滚。
配置格式校验:应用的配置数据存储在配置中心一般都会以一种配置格式存储,比如 Properties、Json、Yaml 等,如果配置格式错误,会导致客户端解析配置失败引起生产故障,配置中心对配置的格式校验能够有效防止人为错误操作的发生,是配置中心核心功能中的刚需。
监听查询:当排查问题或者进行统计的时候,需要知道一个配置被哪些应用实例使用到,以及一个实例使用到了哪些配置。
多环境:在实际生产中,配置中心常常需要涉及多环境或者多集群,业务在开发的时候可以将开发环境和生产环境分开,或者根据不同的业务线存在多个生产环境。如果各个环境之间的相互影响比较小(开发环境影响到生产环境稳定性),配置中心可以通过逻辑隔离的方式支持多环境。
多集群:当对稳定性要求比较高,不允许各个环境相互影响的时候,需要将多个环境通过多集群的方式进行物理隔离。
二、常用配置中心
如果只要能作为分布式存储的服务都作为配置中心,那选择途径就太多了, 比如 Zookeeper 和 ETCD,所以需要提前说明一下。
但是我们选择配置中心时,为什么不优先考虑 Zookeeper 和 ETCD,因为以下两点原因:
没有方便的 UI 管理工具,且缺乏权限、审核、灰度发布、审核机制等;
最重要的是,Zookeeper 和 ETCD 通常定义为服务注册中心,统一配置中心的事情交给专业的工具去解决。
所以给大家介绍的配置中心,主要是以下 4 种,分别为 Disconf、Spring Cloud Config、Apollo 和 Nacos。
2.1 Apollo
GitHub:github.com/apolloconfi…
Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,具备规范的权限、流程治理等特性。
2.1.1 Apollo 框架
Apollo 的框架有点复杂,如果不考虑分布式微服务架构中的服务发现问题,Apollo 的最简架构如下图所示:
这里面包含 Apollo 框架的 4 个核心模块:
ConfigService:提供配置获取接口,提供配置推送接口,服务于 Apollo 客户端。
AdminService:提供配置管理接口,提供配置修改发布接口,服务于管理界面 Portal。
Client:为应用获取配置,支持实时更新,通过 MetaServer 获取 ConfigService 的服务列表,使用客户端软负载 SLB 方式调用 ConfigService。
Portal:配置管理界面,通过 MetaServer 获取 AdminService 的服务列表,使用客户端软负载 SLB 方式调用 AdminService。
调用流程:
ConfigService 是一个独立的微服务,服务于 Client 进行配置获取。
Client 和 ConfigService 保持长连接,通过一种拖拉结合(push & pull)的模式,实现配置实时更新的同时,保证配置更新不丢失。
AdminService 是一个独立的微服务,服务于 Portal 进行配置管理。Portal 通过调用 AdminService 进行配置管理和发布。
ConfigService 和 AdminService 共享 ConfigDB,ConfigDB 中存放项目在某个环境的配置信息。ConfigService/AdminService/ConfigDB 三者在每个环境(DEV/FAT/UAT/PRO)中都要部署一份。
Protal 有一个独立的 PortalDB,存放用户权限、项目和配置的元数据信息。Protal 只需部署一份,它可以管理多套环境。
加上分布式微服务架构中的服务发现,真正的 Apollo 框架如下:
如果你了解 RPC 和注册中心,这幅图其实不难理解:
Eureka 用于注册中心,AP 原则,所以 Config Service 和 Admin Service 的机器列表注册到 Eureka 中;
Client 和 Portal 需要获取注册中心的机器列表,但是由于 Eureka 仅支持 Java 客户端,所以搞个 Meta Server,将 Eureka 的服务发现接口以 HTTP 接口的形式暴露出来;
由于 Meta Server 是集群部署,需要搞个 NginxLB 去找 Meta Server 机器。
所以搞 NginxLB + Meta Server,其实就是为了找 Eureka 中的机器列表配置,Client 和 Portal 拿到这些机器配置,就可以发起调用了,最后就回到我们前面的简图,是不是 So Easy!
2.1.2 Apollo 特性
统一管理不同环境、不同集群的配置:Apollo 提供了一个统一界面集中式管理不同环境(environment)、不同集群(cluster)、不同命名空间(namespace)的配置。同一份代码部署在不同的集群,可以有不同的配置,比如 zk 的地址等。通过命名空间(namespace)可以很方便的支持多个不同应用共享同一份配置,同时还允许应用对共享的配置进行覆盖。
配置修改实时生效(热发布):用户在 Apollo 修改完配置并发布后,客户端能实时(1 秒)接收到最新的配置,并通知到应用程序。
版本发布管理 + 灰度发布
权限管理、发布审核、操作审计:应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误。所有的操作都有审计日志,可以方便的追踪问题。
客户端配置信息监控: 可以在界面上方便地看到配置在被哪些实例使用。
提供 Java 和.Net 原生客户端:提供了 Java 和.Net 的原生客户端,方便应用集成。支持 Spring Placeholder、Annotation 和 Spring Boot 的 ConfigurationProperties,方便应用使用。提供了 Http 接口,非 Java 和.Net 应用也可以方便的使用。
提供开放平台 API:Apollo 自身提供了比较完善的统一配置管理界面,支持多环境、多数据中心配置管理、权限、流程治理等特性。Apollo 出于通用性考虑,对配置的修改不会做过多限制,只要符合基本的格式就能够保存。对于有些使用方,它们的配置可能会有比较复杂的格式,而且对输入的值也需要进行校验后方可保存,如检查数据库、用户名和密码是否匹配。对于这类应用,Apollo 支持应用方通过开放接口在 Apollo 进行配置的修改和发布,并且具备完善的授权和权限控制。
2.2 Spring Cloud Config
2014 年 9 月开源,Spring Cloud 生态组件,可以和 Spring Cloud 体系无缝整合。
2.2.1 工作原理
应用架构图:
工作流程:
在部署环境之前,需要将相应的配置信息推送到配置仓库;
配置服务器启动之后,将配置信息拉取并同步至本地仓库;
配置服务器对外提供 REST 接口,其他所有的配置客户端启动时根据 spring.cloud.config 配置的{application}/{profile}/{label}信息去配置服务器拉取相应的配置。配置仓库支持多样的源,如 Git、SVN、jdbc 数据库和本地文件系统等。
其他应用启动,从配置服务器拉取配置。(配置中心还支持动态刷新配置信息,不需要重启应用,通过 spring-cloud-config-monitor 监控模块,其中包含了/monitor 刷新 API,webhook 调用该端点 API,达到动态刷新的效果。)
2.2.2 特点
提供配置的服务端和客户端支持;
集中式管理分布式环境下的应用配置;
基于 Spring 环境,可以无缝与 Spring 应用集成;
可用于任何语言开发的程序,为其管理与提供配置信息;
默认实现基于 git 仓库,可以进行版本管理。
2.3 Nacos
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
2.1 系统架构
2.2 Nacos 主要特点
服务发现和服务健康监测:
Nacos 支持基于 DNS 和基于 RPC 的服务发现。服务提供者使用原生 SDK、OpenAPI、或一个独立的 Agent TODO 注册 Service 后,服务消费者可以使用 DNS TODO 或 HTTP&API 查找和发现服务。
Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。Nacos 支持传输层 (PING 或 TCP)和应用层 (如 HTTP、MySQL、用户自定义)的健康检查。 对于复杂的云环境和网络拓扑环境中(如 VPC、边缘网络等)服务的健康检查,Nacos 提供了 agent 上报模式和服务端主动检测 2 种健康检查模式。Nacos 还提供了统一的健康检查仪表盘,帮助您根据健康状态管理服务的可用性及流量。
动态配置服务:
动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。
动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。
配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。
Nacos 提供了一个简洁易用的 UI (控制台样例 Demo) 帮助您管理所有的服务和应用的配置。Nacos 还提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。
动态 DNS 服务:
动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单 DNS 解析服务。动态 DNS 服务还能让您更容易地实现以 DNS 协议为基础的服务发现,以帮助您消除耦合到厂商私有服务发现 API 上的风险。
Nacos 提供了一些简单的 DNS APIs TODO 帮助您管理服务的关联域名和可用的 IP:PORT 列表。
2.3 小节
Nacos 是阿里开源的,支持基于 DNS 和基于 RPC 的服务发现。
Nacos 的注册中心支持 CP 也支持 AP,对他来说只是一个命令的切换,随你玩,还支持各种注册中心迁移到 Nacos,反正一句话,只要你想要的他就有。
Nacos 除了服务的注册发现之外,还支持动态配置服务,一句话概括就是 Nacos = Spring Cloud 注册中心 + Spring Cloud 配置中心。
三、配置中心对比和选型
下面对比一下 Spring Cloud Config、Apollo 和 Nacos。
3.1 配置中心对比
灰度发布:Spring Cloud Config 支持通过/bus/refresh 端点的 destination 参数来指定要更新配置的机器,不过整个流程不够自动化和体系化。Apollo 可以直接在控制台上点灰度发布指定发布机器的 IP,接着再全量发布,做得比较体系化。Nacos 目前发布到 0.9 版本,还不支持灰度发布。
权限管理:Spring Cloud Config 依赖 Git 的权限管理能力,开源的 GitHub 权限控制可以分为 Admin、Write 和 Read 权限,权限管理比较完善。Apollo 通过项目的维度来对配置进行权限管理,一个项目的 owner 可以授权给其他用户配置的修改发布权限。Nacos 目前看还不具备权限管理能力。
版本管理 &回滚:Spring Cloud Config、Apollo 和 Nacos 都具备配置的版本管理和回滚能力,可以在控制台上查看配置的变更情况或进行回滚操作。Spring Cloud Config 通过 Git 来做版本管理,更方便些。
配置格式校验:Spring Cloud Config 使用 Git,目前还不支持格式检验,格式的正确性依赖研发人员自己。Apollo 和 Nacos 都会对配置格式的正确性进行检验,可以有效防止人为错误。
监听查询:Spring Cloud Config 使用 Spring Cloud Bus 推送配置变更,Spring Cloud Bus 兼容 RabbitMQ、Kafka 等,支持查询订阅 Topic 和 Consumer 的订阅关系。Apollo 可以通过灰度实例列表查看监听配置的实例列表,但实例监听的配置(Apollo 称为命名空间)目前还没有展示出来。Nacos 可以查看监听配置的实例,也可以查看实例监听的配置情况。基本上,这三个产品都具备监听查询能力,在我们自己的使用过程中,Nacos 使用起来相对简单,易用性相对更好些。
多环境:Spring Cloud Config 支持 Profile 的方式隔离多个环境,通过在 Git 上配置多个 Profile 的配置文件,客户端启动时指定 Profile 就可以访问对应的配置文件。Apollo 也支持多环境,在控制台创建配置的时候就要指定配置所在的环境,客户端在启动的时候指定 JVM 参数 ENV 来访问对应环境的配置文件。Nacos 通过命名空间来支持多环境,每个命名空间的配置相互隔离,客户端指定想要访问的命名空间就可以达到逻辑隔离的作用。
多集群:Spring Cloud Config 可以通过搭建多套 Config Server,Git 使用同一个 Git 的多个仓库,来实现物理隔离。Apollo 可以搭建多套集群,Apollo 的控制台和数据更新推送服务分开部署,控制台部署一套就可以管控多个集群。Nacos 控制台和后端配置服务是部署在一起的,可以通过不同的域名切换来支持多集群。
配置实时推送:Nacos 和 Apollo 配置推送都是基于 HTTP 长轮询,客户端和配置中心建立 HTTP 长联接,当配置变更的的时候,配置中心把配置推送到客户端。Spring Cloud Config 原生不支持配置的实时推送,需要依赖 Git 的 WebHook、Spring Cloud Bus 和客户端/bus/refresh 端点。Nacos 和 Apollo 在配置实时推送链路上是比较简单高效的,Spring Cloud Config 的配置推送引入 Spring Cloud Bus,链路较长,比较复杂。
多语言支持:Spring Cloud 服务于 Java 生态,一开始只是针对 Java 微服务应用,对于非 Java 应用的微服务调用,可以使用 Sidecar 提供了 HTTP API,但动态配置方面还不能很好的支持。Apollo 已经支持了多种语言,并且提供了 open API。其他不支持的语言,Apollo 的接入成本相对较低。Nacos 支持主流的语言,例如 Java、Go、Python、Nodejs、PHP 等,也提供了 open API。
性能对比:Nacos 的读写性能最高,Apollo 次之,Spring Cloud Config 的依赖 Git 场景不适合开放的大规模自动化运维 API。
3.2 配置中心选型
系统架构复杂度: Nacos Config 最为简单,无需消息总线系统,无需 Eureka 等。而 Apollo 与 Spring Cloud Config 系统搭建成本及复杂度较 Nacos 要高很多。
羊群效应: 对于 Spring Cloud Config, Config Client 需要提交配置更新请求。当微服务系 统很庞大时,任何一个 Config Client 的更新请求的提交,都会引发所有“Bus 在线 Config Client“的配置更新请求的提交,即会引发羊群效应。这将会导致 Config Client 的效率下 降,导致整个系统的效率下降。而 Nacos Config 与 Apollo 则是“定点更新”,谁的配置 更新了向谁推送。
自动感知配置更新: Spring Cloud Config 是 Config Client 不提交请求,其是无法感知配置 更新的。但 Nacos 与 Apollo 则是,当 Config Server 中的配置文件发生了变更, Config Client 会自动感知到这个变更,无需 Config Client 端的用户做任何操作。
配置文件类型: Nacos Config 与 Spring Cloud Config 配置文件支持比较多的类型,支持 yaml、 text、 json、 xml、 html、 Properties 等,但 Apollo 只支持 xml、 text、 Properties 类 型, 不支持 yaml
作者:hsfxuebao
链接:https://juejin.cn/post/7170484858538426399
来源:稀土掘金
评论