教程:在 ASP.NET Core 应用中使用动态配置

本教程展示了如何在 ASP.NET Core 应用中启用动态配置更新。 它建立在快速入门中介绍的 Web 应用之上。 应用将利用应用程序配置提供程序库来实现其内置的配置缓存和刷新功能。 在继续操作之前,请先完成使用应用程序配置创建 ASP.NET Core 应用

在本教程中,你将了解如何执行以下操作:

  • 设置应用,使其能够更新配置以响应应用程序配置存储中的更改。
  • 在应用中注入最新配置。

先决条件

完成快速入门:使用应用程序配置创建 ASP.NET Core 应用

添加 sentinel 键

Sentinel 键是完成所有其他键的更改后更新的键。 应用会监视 sentinel 键。 检测到更改时,应用会刷新所有配置值。 与监视所有键来了解更改情况相比,此方法有助于确保应用中配置的一致性,并减少对应用程序配置存储发出的请求总数。

  1. 在 Azure 门户中,打开应用程序配置存储,并选择“配置资源管理器”>“创建”>“键值”。
  2. 输入 TestApp:Settings:Sentinel 作为“键”。 输入 1 作为“值”。 将“标签”和“内容类型”留空 。
  3. 选择“应用”。

从应用配置重载数据

  1. 打开 Program.cs,然后更新之前在快速入门期间添加的 AddAzureAppConfiguration 方法。

    // Load configuration from Azure App Configuration
    builder.Configuration.AddAzureAppConfiguration(options =>
    {
        options.Connect(connectionString)
               // Load all keys that start with `TestApp:` and have no label
               .Select("TestApp:*", LabelFilter.Null)
               // Configure to reload configuration if the registered sentinel key is modified
               .ConfigureRefresh(refreshOptions =>
                    refreshOptions.Register("TestApp:Settings:Sentinel", refreshAll: true));
    });
    

    Select 方法用于加载键名以 TestApp: 开头且无标签的所有键值。 可以多次调用 Select 方法来加载具有不同前缀或标签的配置。 如果与多个应用共享一个应用程序配置存储,则此方法有助于加载仅与当前应用相关的配置,而不是从存储加载所有内容。

    ConfigureRefresh 方法中,注册要监视应用程序配置存储中的更改的键。 Register 方法的 refreshAll 参数指示如果注册的键发生更改,通过 Select 方法指定的所有配置都将被重新加载。

    提示

    可添加对 refreshOptions.SetCacheExpiration 方法的调用以指定配置刷新之间的最短时间。 在此示例中,使用默认值 30 秒。 如果需要减少对应用程序配置存储的请求数量,请调整为更高的值。

  2. 将 Azure 应用程序配置中间件添加到应用的服务集合。

    使用以下代码更新 Program.cs。

    // Existing code in Program.cs
    // ... ...
    
    builder.Services.AddRazorPages();
    
    // Add Azure App Configuration middleware to the container of services.
    builder.Services.AddAzureAppConfiguration();
    
    // Bind configuration "TestApp:Settings" section to the Settings object
    builder.Services.Configure<Settings>(builder.Configuration.GetSection("TestApp:Settings"));
    
    var app = builder.Build();
    
    // The rest of existing code in program.cs
    // ... ...
    
  3. 调用 UseAzureAppConfiguration 方法。 它使应用能够使用应用程序配置中间件为你自动更新配置。

    使用以下代码更新 Program.cs。

    // Existing code in Program.cs
    // ... ...
    
    var app = builder.Build();
    
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }
    
    // Use Azure App Configuration middleware for dynamic configuration refresh.
    app.UseAzureAppConfiguration();
    
    // The rest of existing code in program.cs
    // ... ...
    

在快速入门期间,已将应用设置为使用 ASP.NET Core 中的选项模式。 当应用的底层配置从应用程序配置更新时,通过 IOptionsSnapshot<T> 获得的强类型 Settings 对象会自动更新。 请注意,如果需要进行动态配置更新,则不应使用 IOptions<T>,因为它在应用启动后便不会再读取配置数据。

请求驱动的配置刷新

配置刷新由对 Web 应用的传入请求触发。 如果应用处于空闲状态,则不会发生刷新。 当应用处于活动状态时,应用程序配置中间件会监视 Sentinel 键或在 ConfigureRefresh 调用中注册用于刷新的任何其他键。 每次向应用传入请求时,都会触发中间件。 但是,当设置的缓存过期时间已过去,中间件只会发送请求以检查应用程序配置中的值。

  • 如果向应用程序配置的更改检测请求失败,则应用将继续使用缓存的配置。 当应用有新的传入请求时,将定期进行新的检查更改尝试。
  • 配置刷新与应用传入请求的处理异步进行。 它不会阻止或减缓触发刷新的传入请求。 触发刷新的请求可能不会得到更新的配置值,但是后面的请求会得到新的配置值。
  • 为确保触发中间件,请尽早在请求管道中调用 app.UseAzureAppConfiguration() 方法,这样其他中间件就不会在应用中跳过它。

在本地生成并运行应用

  1. 要通过使用 .NET CLI 生成应用,请在命令 Shell 中运行以下命令:

        dotnet build
    
  2. 生成成功完成后,请运行以下命令以在本地运行 Web 应用:

        dotnet run
    
  3. 打开浏览器窗口,访问 dotnet run 输出中显示的 URL。

    在本地启动快速入门应用

  4. 登录 Azure 门户。 选择“所有资源”,然后选择在快速入门中创建的应用程序配置存储。

  5. 选择“配置资源管理器”并更新以下键的值。 最后记得更新 Sentinel 键。

    密钥
    TestApp:Settings:BackgroundColor green
    TestApp:Settings:FontColor lightGray
    TestApp:Settings:Message Azure 应用配置中的数据 - 现可实时更新!
    TestApp:Settings:Sentinel 2
  6. 多次刷新浏览器。 当缓存在 30 秒后过期时,页面会显示更新的内容。

    在本地启动更新的快速入门应用

日志记录和监视

日志在配置刷新时输出,并包含有关从应用程序配置存储和对应用程序所做的配置更改中检索的键值的详细信息。

  • 调用 services.AddAzureAppConfiguration() 时会自动添加默认 ILoggerFactory。 应用程序配置提供程序使用此 ILoggerFactory 来创建 ILogger 的实例,该实例输出这些日志。 ASP.NET Core默认使用 ILogger 进行日志记录,因此无需进行其他代码更改即可为应用程序配置提供程序启用日志记录。

  • 日志在不同的日志级别输出。 默认级别为 Information

    日志级别 说明
    调试 日志包括你的应用程序对应用程序配置存储中的更改监视的键值的键和标签。 该信息还包括与应用程序已加载的键值相比,这些键值是否已更改。 在此级别启用日志,以便在配置更改未按预期发生时对应用程序进行故障排除。
    信息 日志包括配置刷新期间更新的配置设置的键。 日志中省略配置设置的值,以避免泄露敏感数据。 可以在此级别监视日志,以确保应用程序获取预期的配置更改。
    警告 日志包括配置刷新期间发生的失败和异常。 可以忽略偶尔发生的事件,因为配置提供程序将继续使用缓存的数据,并尝试下次刷新配置。 可以在此级别监视日志,以查找可能指示潜在问题的重复警告。 例如,你轮换了连接字符串,但忘记了更新应用程序。

    可以通过将以下示例添加到 appsettings.json 文件,在 Debug 日志级别启用日志记录。 此示例也适用于所有其他日志级别。

    "Logging": {
        "LogLevel": {
            "Microsoft.Extensions.Configuration.AzureAppConfiguration": "Debug"
        }
    }
    
  • 日志记录类别是 Microsoft.Extensions.Configuration.AzureAppConfiguration.Refresh,它显示在每个日志之前。 下面是每个日志级别的一些示例日志:

    dbug: Microsoft.Extensions.Configuration.AzureAppConfiguration.Refresh[0]
        Key-value read from App Configuration. Change:'Modified' Key:'ExampleKey' Label:'ExampleLabel' Endpoint:'https://examplestore.azconfig.io'
    
    info: Microsoft.Extensions.Configuration.AzureAppConfiguration.Refresh[0]
        Setting updated. Key:'ExampleKey'
    
    warn: Microsoft.Extensions.Configuration.AzureAppConfiguration.Refresh[0]
        A refresh operation failed while resolving a Key Vault reference.
    Key vault error. ErrorCode:'SecretNotFound' Key:'ExampleKey' Label:'ExampleLabel' Etag:'6LaqgBQM9C_Do2XyZa2gAIfj_ArpT52-xWwDSLb2hDo' SecretIdentifier:'https://examplevault.vault.azure.cn/secrets/ExampleSecret'
    

使用 ILogger 是 ASP.NET 应用程序中的首选方法,且如果存在 ILoggerFactory 的实例,则将它优先用作日志记录源。 但是,如果 ILoggerFactory 不可用,也可以通过 .NET Core 应用说明启用和配置日志。 有关详细信息,请参阅 .NET Core 和 ASP.NET Core 中的日志记录

注意

如果使用的是以下任何包的 6.0.0 或更高版本,则可以使用日志记录。

  • Microsoft.Extensions.Configuration.AzureAppConfiguration
  • Microsoft.Azure.AppConfiguration.AspNetCore
  • Microsoft.Azure.AppConfiguration.Functions.Worker

清理资源

如果不想继续使用本文中创建的资源,请删除此处创建的资源组以避免产生费用。

重要

删除资源组的操作不可逆。 将永久删除资源组以及其中的所有资源。 请确保不要意外删除错误的资源组或资源。 如果在包含要保留的其他资源的资源组中创建了本文的资源,请从相应的窗格中单独删除每个资源,而不是删除该资源组。

  1. 登录到 Azure 门户,然后选择“资源组”。
  2. 在“按名称筛选”框中,输入资源组的名称
  3. 在结果列表中,选择资源组名称以查看概述。
  4. 选择“删除资源组”。
  5. 系统会要求确认是否删除资源组。 重新键入资源组的名称进行确认,然后选择“删除”。

片刻之后,将会删除该资源组及其所有资源。

后续步骤

在本教程中,你使得 ASP.NET Core Web 应用能够从应用程序配置中动态刷新配置设置。 若要了解如何使用 Azure 托管标识来简化对应用程序配置的访问,请继续学习下一篇教程。