第 6 章:应用程序配置:不只是环境变量

云原生应用程序的配置管理不仅仅是环境变量的简单使用,更需要结合属性文件、配置服务器等模式,确保分布式系统的灵活性和一致性。本文将系统梳理配置层的设计思路与最佳实践。

本章要点

  • 对应用程序配置的需求
  • 系统配置值和应用程序配置值之间的区别
  • 如何正确使用属性文件
  • 如何正确使用环境变量
  • 配置服务器

在上一章开始时,图 6.1 展示了影响应用程序结果的多种因素,包括请求历史、系统环境和应用程序配置。第 5 章已介绍如何消除请求历史的影响,实现应用程序实例的无状态化。本章将重点讨论系统环境和应用程序配置这两个影响因素。

图 6.1 不管环境中的影响因素有何不同,例如请求历史记录 ( 不同的应用程序实例处理不同的请求 ) 和系统环境值 ( 例如 IP 地址 ),云原生应用程序必须确保结果一致。多个实例的应用程序配置应该相同,但有时可能不同。
图 6.1 不管环境中的影响因素有何不同,例如请求历史记录 ( 不同的应用程序实例处理不同的请求 ) 和系统环境值 ( 例如 IP 地址 ),云原生应用程序必须确保结果一致。多个实例的应用程序配置应该相同,但有时可能不同。

为什么我们要讨论配置?

虽然开发者普遍认为不应将配置硬编码到软件中,并且属性文件已成为主流实践,但云原生环境带来了新的挑战。分布式架构和动态基础设施要求我们重新审视配置管理模式。

动态伸缩与实例配置一致性

云原生应用通常需要动态伸缩,实例数量可能从几十扩展到数千。传统的“手工”配置方式已无法满足需求,必须确保所有实例配置一致,并支持不停机更新。

此外,应用实例的 IP 地址或端口变化也影响服务发现和连接方式,这些配置具有网络效应,需在后续章节详细讨论。

基础设施变化导致配置变化

云平台基础设施频繁变化,如操作系统升级、硬件故障等,都会影响应用配置。以操作系统升级为例,应用实例会迁移到新节点,IP 地址和端口随之变化,应用需自动适应。

图 6.2 应用程序配置变化通常是由基础设施的变化引起的,这些变化可能是预期中的(如图所示的滚动升级),也可能是意外的。
图 6.2 应用程序配置变化通常是由基础设施的变化引起的,这些变化可能是预期中的(如图所示的滚动升级),也可能是意外的。

零停机更新应用程序配置

有时仅需更新配置而无需重启应用,如版权信息或密码轮换。理想方式是通过抽象和参数化,将配置值在合适时机注入应用程序,实现可重复、可验证的配置管理模式。

应用程序的配置层

十二要素应用程序(12factor.net)推荐将配置存储在环境变量中,提升可移植性和运维一致性。以 Java 为例,可通过 System.getenv 获取环境变量。

但环境变量并非所有配置的最佳方式。更优雅的做法是引入专门的配置层,将所有配置参数集中定义,便于管理和注入。属性文件是实现配置层的常见方式,各主流语言均有支持。

图 6.3 应用程序有一个特定的配置层,它可以同时支持系统环境和应用程序配置。这一层使得代码实现只管使用配置值,而不用管这些值是如何提供的。
图 6.3 应用程序有一个特定的配置层,它可以同时支持系统环境和应用程序配置。这一层使得代码实现只管使用配置值,而不用管这些值是如何提供的。

属性文件的优势在于集中管理所有配置参数,便于开发和运维人员理解和维护。缺点是常被打包进可部署构件,导致不同环境需不同构建流程。建议将属性文件作为配置参数规范,并通过环境变量或其他方式覆盖默认值。

例如,属性文件中的 IP 地址配置可采用如下方式:

  • ipaddress=${INSTANCE_IP:127.0.0.1}

表示优先使用环境变量 INSTANCE_IP,否则采用默认值 127.0.0.1。

图 6.4 属性文件结合环境变量实现灵活配置
图 6.4 属性文件结合环境变量实现灵活配置

注入系统/环境值

系统值通常由基础设施提供,如实例 IP 地址、端口等。云环境下,应用实例频繁变化,需通过环境变量动态注入这些值。

实际案例:Kubernetes 环境变量配置

在 Kubernetes 部署清单中,可通过 env 字段定义环境变量。例如,将 pod 的 IP 地址注入到应用:

  • INSTANCE_IP 通过 status.podIP 自动赋值。

应用通过属性文件引用该环境变量,实现配置注入。

图 6.6 Kubernetes 负责部署和管理应用程序的实例,建立部署清单中定义的环境变量,并且从它为应用程序建立的基础设施中获取值。
图 6.6 Kubernetes 负责部署和管理应用程序的实例,建立部署清单中定义的环境变量,并且从它为应用程序建立的基础设施中获取值。

实际操作中,可通过命令行查看容器内环境变量,验证配置是否正确注入。

注入应用程序配置

应用程序配置如密码、连接信息等,需持久化、版本控制并安全管理。推荐使用源代码控制系统(如 Git)和配置服务器(如 Spring Cloud Configuration Server,SCCS)统一管理。

配置服务器介绍与实践

配置服务器通过 HTTP 接口为应用提供配置数据,支持多环境、多版本管理。实际操作流程如下:

  • 在 Git 仓库中维护配置文件(如 mycookbook.properties),包含服务密码等敏感信息。
  • SCCS 部署后,应用通过环境变量指定配置服务器地址,自动拉取并注入配置值。
图 6.8 应用程序配置层依赖于属性文件来注入值,这些值是通过配置服务器获得的。
图 6.8 应用程序配置层依赖于属性文件来注入值,这些值是通过配置服务器获得的。

应用代码通过注解或配置层获取配置服务器注入的参数,实现分布式配置一致性。

安全与最佳实践

  • 密码等敏感信息应加密存储,避免明文传递和日志输出。
  • 推荐使用专用安全配置仓库(如 Vault)管理敏感配置。
  • 配置变更需通过版本控制系统统一管理,避免手动修改。

应用配置与系统配置的统一模式

属性文件作为系统配置和应用配置的公共抽象层,系统配置通过环境变量注入,应用配置通过配置服务器注入。两者模式一致,便于统一管理和扩展。

图 6.9 统一配置层模式
图 6.9 统一配置层模式

总结

  • 云原生架构需重新评估配置管理技术,结合新旧方法实现最佳实践。
  • 属性文件是配置管理的核心,环境变量适合系统配置,配置服务器适合应用配置。
  • 应用配置应像源代码一样进行版本控制和访问管理。
  • 配置服务器可实现分布式配置注入,提升灵活性和一致性。
  • 配置变更需结合应用生命周期,确保多实例和多服务间的协调更新。

文章导航

独立页面

这是书籍中的独立页面。

书籍首页

评论区