从单体架构与SOA转向微服务,配置中心这个服务可能会有些陌生,尤其是单体架构,几乎不存在这样的需求。
我们过去的配置变更方式涉及手动修改各节点的配置文件。对于拥有多个实例的情况,我们必须逐个节点进行修改,并在完成修改后分阶段重新启动或重载服务。在先前的架构中,这种方法并没有引起太大的问题。然而,考虑到我们现在的业务情景,尤其是车贷系统规模相对较小,已经拥有大约30个服务。如果考虑到高可用性(HA),服务实例的数量将至少翻倍,即至少60个服务实例。在这种情况下,如果我们需要进行较为全局性的配置更改,比如数据库连接地址,那将是一项庞大而繁琐的工程。
鉴于当前情况,我们自然而然地考虑将所有配置集中存储在一个地方。最简单的方法可能是使用NAS(网络附加存储)进行共享存储。随后,我们可以将配置分为两个主要部分:全局配置和服务本身的配置。这种方式的配置管理如下图所示:
这种集中化配置的方法确实有效,但我们需要考虑到如果NAS发生故障会带来的问题。为了解决这一点,我们可以考虑将NAS部署为一个集群,以提高可用性。另一种选择是利用云厂商提供的对象存储服务,这样可以进一步提高配置的可靠性和可用性。这种集中化配置的方式实际上是配置中心的雏形,但在生产环境中,我们可能还需要满足其他一些要求。
配置中心在解决问题场景上有广泛的应用,例如:
线上问题排查: 在传统情况下,生产日志通常设置为INFO级别,但排查问题可能需要调整为DEBUG级别。通过配置中心,我们可以在不重启服务的情况下动态地变更日志级别,避免由于环境变更导致问题无法重现的情况发生。
容灾处理: 在混合云架构中,特别是应用上云而数据仍在自己的IDC时,容灾处理至关重要。配置中心可以快速完成从主库切换到从库的配置,实现主库故障时的无缝切换。
活动管理: 针对ToC的公司,定期进行营销活动是常见的操作。在活动期间,系统负载和质量的要求通常较高,可能需要特殊的配置管理,如连接池、队列、线程、降级等。配置中心能够灵活管理针对不同活动的配置,确保系统在活动期间能够高效运行。
这些场景展示了配置中心在提高系统灵活性、降低维护成本、应对特殊需求方面的价值。通过动态管理配置,我们能够更好地适应不同的业务场景和需求,提高系统的稳定性和可维护性。
- 我们期望配置中心能够统一管理散落在各个地方(数据库、本地配置文件、启动参数、JNDI等)的配置。这些配置通常以键值对(K-V)的形式表示,以便于在不同环境中灵活使用。这种集中的配置管理方式有以下优势:
- 一致性: 通过配置中心,我们能够确保系统中的配置信息保持一致,而不会因为分散在不同地方而导致不一致的问题。
- 集中管理: 集中管理配置能够简化配置的维护和更新过程,而不必在每个节点都手动进行修改。
- 动态性: 配置中心应具备动态配置的能力,允许在运行时动态调整配置,而无需重启服务。这在快速响应业务变化和排查问题时尤为重要。
- 键值对形式: 配置中心一般采用键值对的形式,使得配置的表示简单而灵活。这种形式非常适合表示各种参数和属性。
需要注意的是,确实有一些配置,如logback.xml、Groovy/JS动态脚本、多媒体文件等,可能并不适合通过配置中心进行管理。对于这些类型的配置,我们可能需要采用其他方式,例如使用版本控制系统或特定的配置文件管理工具。配置中心主要关注那些以键值对形式存在且需要在运行时动态调整的配置信息。
- 在考虑生产环境中使用的配置中心时,版本化和变更审计是至关重要的考虑因素。
版本化: 一个成熟的配置中心需要支持配置的版本化。当我们进行全局配置修改后,系统应该能够自动或手动创建一个新版本。这样,如果修改引入了问题,我们可以迅速回滚到先前的配置版本,避免生产事故。
变更审计: 配置中心应该记录每次配置的变更,包括修改的时间、修改人员等信息。这种变更审计功能对于问题排查、追责以及系统安全性都是至关重要的。如果出现问题,我们可以追溯到具体的配置变更,帮助更快地定位和解决问题。
通过版本化和变更审计,配置中心可以提供更高级别的可追溯性和可管理性,使得在配置修改引发问题时能够更加从容地应对,同时也有助于建立更严密的变更管理流程。
- 在一个实际的生产环境中,配置中心需要支持灵活的配置管理,包括依赖继承、环境区分、场景区分等功能。
依赖继承: 配置中心应支持配置的依赖继承关系。例如,某个微服务可能有自身的配置,同时也会依赖于一些公共配置。配置中心需要能够自动合并服务自身配置和公共配置,确保微服务获取到完整的配置信息。
环境区分: 不同的环境(如开发、测试、预发、生产)可能需要不同的配置。配置中心应该能够根据环境的不同提供相应的配置。这样,同一份配置在不同环境中可以有不同的取值,确保在不同阶段的部署和测试中能够使用适当的配置。
场景区分: 针对特殊活动或场景(如双11、618大促),配置中心也应支持特殊配置。这样,我们可以根据不同的业务活动设置特定的配置,确保在活动期间系统能够按照特定的要求运行。
通过这些功能,配置中心能够更好地适应多样化的需求,提供灵活的配置管理。这样的设计使得系统能够在不同的环境和业务场景下轻松地切换配置,确保系统在不同条件下都能以最优的状态运行。
- 对于一个实际的生产环境,配置中心的优秀设计需要支持动态刷新配置并应用到服务实例,同时提供分批次或灰度发布的策略。
动态刷新配置: 优秀的配置中心应当支持动态刷新配置,使得配置的变更可以即时生效,而不需要重启整个服务。为实现这一点,服务通常会集成配置中心的SDK,SDK能够接收到新的配置并通知服务实例进行配置重载。对于有缓存设计的功能,服务自身需要处理配置的更新逻辑,确保配置的变更能够正确应用到运行中的服务。
分批次或灰度发布: 配置中心需要支持分批次或灰度发布,以确保在配置变更时能够逐步验证新配置的稳定性。这可以通过按照指定的策略先刷新一批服务实例来实现。服务实例需要提供标签,用于区分不同的实例,例如,按地域分发的服务可以带上地域标签,从而实现按地域进行分批次或灰度更新。
弱依赖设计: 为确保服务在脱离配置中心的情况下依然能够正常运行,通常采用弱依赖的设计。服务在启动时向配置中心获取配置并缓存到本地,在配置中心推送配置或服务定时主动拉取最新配置并更新缓存。这种设计可以保证在配置中心或网络故障时各服务依然可以正常运行,降低了对配置中心的强依赖性。
通过这些设计,配置中心在服务管理方面能够提供更高度的灵活性和可靠性,确保配置变更的顺畅过渡,同时服务依然能够在各种情况下保持稳定运行。
总体而言,配置中心的设计核心包括以下关键要求:
- 集中化管理与配置切片: 配置中心应支持集中化管理所有配置,并能按照不同的维度进行切片管理,包括全局级与服务级、不同环境(如生产、预发、测试、开发)以及特殊活动等。
- 版本化与变更审计: 配置中心需要具备版本化和变更审计功能,以确保配置变更具有历史记录,方便回滚和审计。可以采用类似GIT的方式管理配置的版本。
- 动态刷新: 配置中心应当支持动态刷新配置,并能够按照一定的策略实现动态刷新。这包括有服务依赖时先刷新被依赖的服务,以及按批次或灰度刷新多实例的情况。
- 高可用: 配置中心本身需要足够健壮,同时最好能够作为一个普通服务注册到注册中心,形成整体的高可用架构。
- 弱依赖: 服务在运行期间不应强依赖配置中心,需要实施好配置获取及缓存策略,以确保在配置中心或网络故障时使用缓存配置,不影响服务正常运行。
- Push/Pull: 配置更新可以采用Push或Pull两种方式。Push方式能够实现对配置变更的实时感知,但对配置中心的要求较高。
- SDK支持: 配置中心应提供相应的SDK,以便服务能够实现配置的刷新和缓存,确保即便在配置中心宕机或网络不通的情况下,不会影响服务的正常运行。
在微服务架构中,配置中心被视为一个重要的核心服务。市场上有一些成熟的独立配置中心,其中一些与特定的微服务框架配套使用。
例如,Spring Cloud项目通常会使用Spring Cloud Config作为配置中心。Spring Cloud Config提供了与Spring Cloud配套的解决方案,使得在Spring Cloud环境中,配置的管理变得更为便捷。它能够支持分布式系统中的外部配置,允许将配置存储在集中的服务器上。
除此之外,还有其他独立配置中心,如百度开源的Disconf和携程开源的Apollo。这些配置中心都在不同的场景下得到了广泛应用,提供了丰富的功能来满足微服务架构中配置管理的需求。
对于Spring Cloud项目,一般情况下,Spring Cloud Config能够很好地满足配置管理的要求。而对于非Spring Cloud项目,可以考虑使用其他成熟的配置中心,比如Apollo。在一些特殊情况下,也可以考虑基于Etcd等技术进行定制化开发,以满足特定需求和场景的配置管理要求。不同的配置中心适用于不同的项目背景和技术栈,选择适合自身项目的配置中心是关键。