微服务-常见配置中心工作原理

2,386 阅读17分钟

欢迎大家关注 github.com/hsfxuebao ,希望对大家有所帮助,要是觉得可以的话麻烦给点一下Star哈

0. 环境

  • nacos版本:1.4.1
  • Spring Cloud : 2020.0.2
  • Spring Boot :2.4.4
  • Spring Cloud alibaba: 2.2.5.RELEASE
  • Spring Cloud openFeign 2.2.2.RELEASE

测试代码:github.com/hsfxuebao/s…

1. 配置中心基础

1.1 为什么要用配置中心?

  • 配置实时生效:传统的静态配置方式要想修改某个配置只能修改之后重新发布应用,要实现动态性,可以选择使用数据库,通过定时轮询访问数据库来感知配置的变化。轮询频率低感知配置变化的延时就长,轮询频率高,感知配置变化的延时就短,但比较损耗性能,需要在实时性和性能之间做折中。配置中心专门针对这个业务场景,兼顾实时性和一致性来管理动态配置;

  • 配置管理流程:配置的权限管控、灰度发布、版本管理、格式检验和安全配置等一系列的配置管理相关的特性,也是配置中心不可获取的一部分;

  • 分布式场景:随着采用分布式的开发模式,项目之间的相互引用随着服务的不断增多,相互之间的调用复杂度成指数升高,每次投产或者上线新的项目时苦不堪言,需要引用配置中心治理。

1.2 配置中心支持功能

  • 灰度发布:配置的灰度发布是配置中心比较重要的功能,当配置的变更影响比较大的时候,需要先在部分应用实例中验证配置的变更是否符合预期,然后再推送到所有应用实例。

  • 权限管理:配置的变更和代码变更都是对应用运行逻辑的改变,重要的配置变更常常会带来核弹的效果,对于配置变更的权限管控和审计能力同样是配置中心重要的功能。

  • 版本管理&回滚:当配置变更不符合预期的时候,需要根据配置的发布版本进行回滚。

  • 配置格式校验:应用的配置数据存储在配置中心一般都会以一种配置格式存储,比如Properties、Json、Yaml等,如果配置格式错误,会导致客户端解析配置失败引起生产故障,配置中心对配置的格式校验能够有效防止人为错误操作的发生,是配置中心核心功能中的刚需。

  • 监听查询:当排查问题或者进行统计的时候,需要知道一个配置被哪些应用实例使用到,以及一个实例使用到了哪些配置。

  • 多环境:在实际生产中,配置中心常常需要涉及多环境或者多集群,业务在开发的时候可以将开发环境和生产环境分开,或者根据不同的业务线存在多个生产环境。如果各个环境之间的相互影响比较小(开发环境影响到生产环境稳定性),配置中心可以通过逻辑隔离的方式支持多环境。

  • 多集群:当对稳定性要求比较高,不允许各个环境相互影响的时候,需要将多个环境通过多集群的方式进行物理隔离。

2. 常用配置中心

如果只要能作为分布式存储的服务都作为配置中心,那选择途径就太多了, 比如ZookeeperETCD,所以需要提前说明一下。

但是我们选择配置中心时,为什么不优先考虑Zookeeper和ETCD,因为以下两点原因:

  • 没有方便的UI管理工具,且缺乏权限、审核、灰度发布、审核机制等;

  • 最重要的是,ZookeeperETCD通常定义为服务注册中心,统一配置中心的事情交给专业的工具去解决。

所以给大家介绍的配置中心,主要是以下4种,分别为 Disconf、Spring Cloud Config、Apollo 和 Nacos

2.1 Apollo

GitHub:github.com/apolloconfi…

Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,具备规范的权限、流程治理等特性。

2.1.1 Apollo框架

Apollo的框架有点复杂,如果不考虑分布式微服务架构中的服务发现问题,Apollo的最简架构如下图所示:

image.png

这里面包含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框架如下:

image.png

如果你了解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

GitHub:github.com/spring-clou…

2014年9月开源,Spring Cloud 生态组件,可以和Spring Cloud体系无缝整合。

2.2.1 工作原理

应用架构图:

image.png

工作流程:

  • 在部署环境之前,需要将相应的配置信息推送到配置仓库;

  • 配置服务器启动之后,将配置信息拉取并同步至本地仓库;

  • 配置服务器对外提供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.io/zh-cn/docs/…

image.png

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

image.png

2.1 系统架构

image.png

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配置中心

3. 配置中心对比和选型

下面对比一下 Spring Cloud Config、Apollo 和 Nacos。

功能特性重要性spring-cloud-configApollodisconfNacos
静态配置管理基于file支持支持支持
动态配置管理支持支持支持支持
统一管理无,需要github支持支持支持
多环境无,需要github支持支持支持
本地配置缓存支持支持支持
配置锁支持不支持不支持不支持
配置校验
配置生效时间重启生效,或手动refresh生效实时实时实时
配置更新推送需要手工触发支持支持支持
配置定时拉取支持配置更新目前依赖事件驱动, client重启或者server端推送操支持
用户权限管理无,需要github支持支持支持
授权、审核、审计无,需要github支持支持
配置版本管理Git做版本管理界面上直接提供发布历史和回滚按钮操作记录有落数据库,但无查询接口界面操作,支持回滚
配置合规检测不支持支持(但还需完善)支持
实例配置监控需要结合spring admin支持支持,可以查看每个配置在哪些机器上加载支持
灰度发布不支持支持不支持部分更新支持
告警通知不支持支持,邮件方式告警支持,邮件方式告警支持

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

参考文章

springcloud-source-study学习github地址
Spring Cloud Alibaba源码解析
Nacos 配置中心源码分析
图文解析 Nacos 配置中心的实现
nacos 动态配置源码解析