Azure 应用程序配置最佳做法

本文介绍了使用 Azure 应用程序配置时的常见模式和最佳做法。

键分组

应用程序配置提供了两个用于组织键的选项:

  • 键前缀
  • 标签

可以使用一个或两个选项对键进行分组。

键前缀是键的开头部分。 可以通过在键名称中使用相同的前缀对一组键进行逻辑分组。 前缀可以包含由分隔符连接的多个构成部分,如 /(类似于 URL 路径),以形成一个命名空间。 当在一个应用程序配置存储中存储多个应用程序和微服务的键时,此类层次结构非常有用。

需要记住的重要一点是,键是你的应用程序代码所引用的内容,用于检索相应设置的值。 键不应进行更改,否则每次发生更改时都必须修改你的代码。

标签是键上的一个属性。 它们用于创建键的变体。 例如,可以将标签分配给多个版本的键。 版本可以是迭代、环境或某些其他上下文信息。 你的应用程序可以通过指定其他标签来请求一组完全不同的键值。 其结果是,所有关键引用在代码中均保持不变。

键-值组合

应用程序配置将使用它存储的所有键视为独立的实体。 应用程序配置不会尝试推断键之间的任何关系,也不会基于键的层次结构来继承键值。 但是,可通过在应用程序代码中将标签和适当的配置堆叠配合使用来聚合多组键。

接下来举例说明。 假设你有一个名为“Asset1”的设置,其值可能因开发环境而异。 创建一个名为“Asset1”的键,其中包含一个空标签和一个名为“Development”的标签。 在第一个标签中,为“Asset1”输入默认值,在后者中为“Development”输入特定值。

在代码中,首先检索没有任何标签的键值,然后使用“开发”标签第二次检索相同的一组键值。 第二次检索该值时,将覆盖先前的键值。 .NET 配置系统允许“堆叠”多组配置数据。 如果一个键存在于多个集中,则使用包含该键的最后一个集。 通过新式编程框架(如 .NET),如果使用本机配置提供程序访问应用程序配置,则可以免费获得此堆叠功能。 以下代码片段演示如何在 .NET 应用程序中实现堆叠:

// Augment the ConfigurationBuilder with Azure App Configuration
// Pull the connection string from an environment variable
configBuilder.AddAzureAppConfiguration(options => {
    options.Connect(configuration["connection_string"])
           .Select(KeyFilter.Any, LabelFilter.Null)
           .Select(KeyFilter.Any, "Development");
});

使用标签为不同环境启用不同配置提供一个完整的示例。

对外部数据的引用

应用程序配置旨在存储通常保存在配置文件或环境变量中的任何配置数据。 但是,某些类型的数据可能更适合驻留在其他源中。 例如,将机密存储在 Key Vault 中,将文件存储在 Azure 存储中,将成员资格信息存储在 Microsoft Entra 组中,或者将客户列表存储在数据库中。

可以通过以键值方式保存对外部数据的引用,仍然利用应用程序配置。 可以使用内容类型来区分每个数据源。 当应用程序读取引用时,它会从引用的源中加载实际数据,前提是该应用程序具有对源的必要权限。 如果更改外部数据的位置,只需在应用程序配置中更新引用,而无需更新并重新部署整个应用程序。

应用程序配置 Key Vault 引用功能就是这样一个例子。 它允许在必要时更新应用程序所需的机密,而基础机密本身仍保留在 Key Vault 中。

应用程序配置启动

若要访问应用程序配置存储,可以使用其连接字符串,该字符串可在 Azure 门户中获取。 由于连接字符串包含凭据信息,因此它们被视为机密。 这些机密需要存储在 Azure Key Vault 中,你的代码必须向 Key Vault 进行身份验证才能检索这些机密。

更好的选择是使用 Microsoft Entra ID 中的托管标识功能。 通过托管标识,只需使用应用程序配置终结点 URL 即可启动对应用程序配置存储的访问。 可以将 URL 嵌入到应用程序代码中(例如嵌入到 appsettings.json 文件中)。 有关详细信息,请参阅使用托管标识来访问应用配置

Azure Kubernetes 服务对应用配置的访问权限

托管在 Azure Kubernetes 服务 (AKS) 中的工作负荷可使用以下选项访问 Azure 应用程序配置。 这些选项通常也适用于 Kubernetes。

  • Azure 应用程序配置 Kubernetes 提供程序添加到 AKS 群集。 Kubernetes 提供程序在群集中作为 Pod 运行。 它可以根据应用程序配置商店中的键值和 Key Vault 引用来构建 ConfigMap 和机密。 ConfigMap 和机密可作为环境变量或装载的文件使用,无需修改应用程序代码。 如果有多个应用程序在同一 AKS 群集中运行,则它们都可以访问生成的 ConfigMap 和机密,无需分别对应用配置发出请求。 Kubernetes 提供程序还支持动态配置更新。 如果可行,建议使用此选项。

  • 更新应用程序以使用 Azure 应用程序配置提供程序库。 提供程序库在许多框架和语言中可用,例如 ASP.NET.NETJava SpringJavaScript/Node.jsPython。 此方法使你能够完全访问应用配置的功能,其中包括动态配置和功能管理。 可以精细控制每个应用程序要加载哪些数据,以及从哪个应用配置存储加载数据。

  • 使用 Helm 来与 Kubernetes 部署集成 如果不想更新应用程序或向 AKS 群集添加新 Pod,可以选择通过部署使用 Helm 将数据从应用程序配置引入 Kubernetes 群集。 此方法使应用程序能够继续从 Kubernetes 变量和机密访问配置。 每当希望应用程序合并新的配置更改时,都可以运行 Helm 升级。

通过应用服务或 Azure Functions 访问应用配置

使用应用配置提供程序或 SDK 库直接在应用程序中访问应用配置。 此方法使你能够完全访问应用配置的功能,其中包括动态配置和功能管理。 在应用服务或 Azure Functions 上运行的应用程序可以通过以下任一方法获取对应用配置存储的访问权限:

  • 在应用服务或 Azure Functions 上启用托管标识,并向其授予对应用配置存储的访问权限。 有关详细信息,请参阅使用托管标识访问应用配置
  • 在应用服务或 Azure Functions 的“应用程序设置”中存储应用配置存储的连接字符串。 为了增强安全性,请将连接字符串存储在 Key Vault 中,并从应用服务或 Azure Functions 引用它

还可以将应用配置数据作为“应用程序设置”或环境变量,使之可供应用程序访问。 使用此方法,可以避免更改应用程序代码。

减少对应用程序配置发出的请求

对应用程序配置的请求过多可能会导致限制或超额费用。 若要减少发出的请求数,方法如下:

  • 提高刷新超时,尤其是在配置值不经常更改的情况下。 使用 SetCacheExpiration 方法指定新的刷新超时。

  • 集中监视一个 sentinel 键,而不是监视独立的多个键。 仅当 sentinel 键更改时才刷新所有配置。 有关示例,请参阅在 ASP.NET Core 应用中使用动态配置

  • 使用 Azure 事件网格在配置更改时接收通知,而不是通过不断轮询来发现更改。 有关详细信息,请参阅使用事件网格接收应用程序配置数据更改通知

  • 启用应用程序配置存储的异地复制,并将请求分散到多个副本。 例如,为全局部署的应用程序使用每个地理区域的不同副本。 每个应用程序配置副本都有各自的请求配额。 此设置提供了一个模型,可针对暂时性和区域性中断提供可伸缩性和增强的复原能力。

将配置数据导入到应用程序配置中

应用程序配置提供了使用 Azure 门户或 CLI 从当前配置文件批量导入配置设置的选项。 还可以使用相同的选项从应用程序配置中导出键值,例如在相关存储之间导出键值。 若要设置与 GitHub 或 Azure DevOps 存储库的持续同步,可以使用 GitHub 操作Azure 管道推送任务,这样可以继续使用现有的源代码管理实践,同时又能获得应用程序配置的优势。

应用程序配置中的多区域部署

如果应用程序部署在多个区域中,建议启用应用程序配置存储的异地复制。 可以让应用程序主要连接到与部署应用程序实例的区域匹配的副本,并允许它们故障转移到其他区域中的副本。 此设置可最大程度地减少应用程序和应用程序配置之间的延迟,在每个副本具有单独的限制配额时分散负载,并增强应用程序对暂时性和区域性中断的复原能力。 有关详细信息,请参阅复原能力和灾难恢复

构建具有高复原能力的应用

应用通常依赖配置来启动,这使得 Azure 应用程序配置的高可用性至关重要。 为了提高复原能力,应用程序应利用应用程序配置的可靠性功能,并考虑根据具体要求采取以下措施。

  • 在具有 Azure 可用性区域支持的区域中进行设置。 可用性区域使应用程序能够恢复数据中心中断。 应用程序配置为所有客户提供区域冗余,无需任何额外费用。 建议在具有可用性区域支持的区域创建应用程序配置存储区。 可以找到应用程序配置已启用可用性区域支持的区域列表
  • 启用异地复制,并允许应用程序在副本之间进行故障转移。 此设置提供了可伸缩性模型,并增强了针对临时失败和区域性中断的复原能力。 有关详细信息,请参阅复原能力和灾难恢复
  • 使用安全部署做法部署配置。 不正确或意外的配置更改经常会导致应用程序故障时间。 应该尽可能避免直接从 Azure 门户进行影响生产的配置更改。 在安全部署实践 (SDP) 中,使用渐进暴露部署模型来最大限度地减少部署引发问题的潜在爆炸半径。 如果采用 SDP,可以在将配置快照部署到生产环境之前构建并测试它。 在部署期间,可以更新应用程序的实例以逐渐获取新快照。 如果检测到问题,可以通过重新部署最后一个已知良好 (LKG) 快照来回滚更改。 快照是不可变的,保证了所有部署的一致性。 可以将快照与动态配置一起使用。 使用快照进行基础配置,使用动态配置进行紧急配置替代和功能标志。
  • 将配置包含在应用程序中。 如果希望确保应用程序始终可以访问配置的副本,或者如果希望完全避免应用程序配置上的运行时依赖项,可以在构建或发布期间从应用程序配置中拉取配置,并将其包含在应用程序中。 要了解更多信息,请查看将应用程序配置与 CI/CD 管道Kubernetes 部署集成的示例。
  • 使用应用程序配置提供程序。 应用程序在实现高复原能力方面发挥着关键作用,因为它们可以解决运行时出现的问题,如网络问题,并更快地对失败做出响应。 应用程序配置提供程序提供了一系列内置的复原能力功能,包括自动副本发现、副本故障转移、具有可自定义超时的启动重试、配置缓存以及用于可靠配置刷新的自适应策略。 强烈建议使用应用程序配置提供程序以从这些功能中获益。 如果不能这样做,则应考虑在自定义解决方案中实现类似的功能,以实现最高级别的复原能力。

应用配置中的客户端应用程序

在客户端应用程序中使用应用配置时,请确保考虑两个主要因素。 第一,如果要在客户端应用程序中使用连接字符串,则存在向公众公开应用配置存储的访问密钥的风险。 第二,客户端应用程序的典型规模可能会导致向应用配置存储发出的请求过多,这可能会导致费用超额或导致限制。 有关限制的详细信息,请参阅常见问题解答

为了解决这些问题,建议在客户端应用程序和应用配置存储之间使用代理服务。 该代理服务可以安全地向应用配置存储进行身份验证,而不会有泄露身份验证信息的安全问题。 可以通过使用应用配置提供程序库之一来生成代理服务,这样就可以利用内置缓存和刷新功能来优化发送到应用配置的请求量。 若要详细了解如何使用应用配置提供程序,请参阅快速入门和教程中的文章。 该代理服务会将其缓存中的配置提供给客户端应用程序,这样你就可以避免此部分介绍的两个潜在问题。

应用配置中的多租户应用程序

多租户应用程序基于一个体系结构构建,其中应用程序的共享实例服务于多个客户或租户。 例如,你可能有一个电子邮件服务,可为用户提供单独的帐户和自定义体验。 应用程序通常为每个租户管理不同的配置。 以下是有关在多租户应用程序中使用应用配置的一些体系结构注意事项。

配置即代码

配置即代码是一种管理源代码控制系统(例如 git 存储库)下的配置文件的操作。 使用它可提供很多好处:可跟踪性和任何配置更改的批准流程等。 如果你采用配置作为代码,应用程序配置具备工具,可用于帮助管理文件中的配置数据,并将这些数据部署为你的内部版本、发行版本或 CI/CD 流程的一部分。 这样,应用程序就可以从应用程序配置存储访问最新数据。

  • 对于 GitHub,可以为存储库启用应用程序配置同步 GitHub 操作。 每当合并拉取请求时,对配置文件的更改都会自动同步到应用程序配置。
  • 对于 Azure DevOps,可以在生成或发布管道中包含 Azure 应用程序配置推送(Azure 管道任务)以进行数据同步。
  • 还可以在 CI/CD 系统中使用 Azure CLI 将配置文件导入应用程序配置。 有关详细信息,请参阅 az appconfig kv import

使用此模型,你可以在将数据提交到应用程序配置之前添加验证和测试步骤。 如果使用多个应用程序配置存储,则还可以将配置数据以增量方式或一次性全部推送给它们。

后续步骤