教程:在 .NET 后台服务中使用动态配置

应用程序配置中的数据可在 .NET 应用程序中作为应用设置加载。 有关详细信息,请参阅此快速入门。 但是,根据 .NET 的设计,只能在应用程序重启时刷新应用设置。 应用配置 .NET 提供程序是一个 .NET Standard 库。 它支持动态缓存和刷新配置,而无需重启应用程序。 本教程演示如何在 .NET 后台服务中实现动态配置更新。

本教程介绍如何执行下列操作:

  • 设置 .NET 后台服务,使其能够更新配置以响应应用程序配置存储区中的更改。
  • 在后台服务中使用最新配置。

先决条件

添加键值

将以下键值添加到应用程序配置存储区,并让“标签”和“内容类型”保留默认值。 有关如何使用 Azure 门户或 CLI 将键值添加到存储区的详细信息,请转到创建键值

密钥
TestApp:Settings:Message Azure 应用配置的数据

创建 .NET 后台服务

使用 .NET 命令行接口 (CLI) 创建新的 .NET 应用项目。 通过 Visual Studio 使用 .NET CLI 的优点是,它可用于 Windows、macOS 和 Linux 平台。

  1. 为项目新建一个文件夹。

  2. 在新文件夹中,运行以下命令以创建新的 .NET 后台服务项目:

    dotnet new worker
    

从应用配置重载数据

  1. 通过运行以下命令,添加对 Microsoft.Extensions.Configuration.AzureAppConfiguration NuGet 包的引用:

    dotnet add package Microsoft.Extensions.Configuration.AzureAppConfiguration
    
  2. 运行以下命令,还原项目包:

    dotnet restore
    
  3. 打开文件 Program.cs 并添加以下语句:

    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Configuration.AzureAppConfiguration;
    
  4. 使用 Microsoft Entra ID(建议)或连接字符串连接到应用配置。

    可以使用 DefaultAzureCredential 向应用程序配置存储区进行身份验证。 按照说明为凭据分配应用程序配置数据读取者角色。 在运行应用程序之前,请务必留出足够的时间来传播权限。

    // Existing code in Program.cs
    // ... ...
    
    var builder = Host.CreateApplicationBuilder(args);
    
    builder.Configuration.AddAzureAppConfiguration(options =>
    {
        string endpoint = Environment.GetEnvironmentVariable("Endpoint"); 
        options.Connect(new Uri(endpoint), new DefaultAzureCredential());
            // Load all keys that start with `TestApp:`.
            .Select("TestApp:*")
            // Configure to reload the key 'TestApp:Settings:Message' if it is modified.
            .ConfigureRefresh(refreshOptions =>
            {
                refreshOptions.Register("TestApp:Settings:Message");
            });
    
        // Register the refresher so that the Worker service can consume it through DI
        builder.Services.AddSingleton(options.GetRefresher());
    });
    
    // The rest of existing code in Program.cs
    // ... ...
    

    ConfigureRefresh 方法中,应用程序配置存储中的密钥注册用于监视更改。 Register 方法具有一个可选的布尔参数 refreshAll,该参数可用于指示在注册的密钥发生更改时是否应刷新所有配置值。 在此示例中,只会刷新密钥 TestApp:Settings:Message。 对于注册刷新的所有设置,尝试新刷新之前的默认缓存到期时间为 30 秒。 可以通过调用 AzureAppConfigurationRefreshOptions.SetCacheExpiration 方法来更新它。

  5. 打开 Worker.cs。 将 IConfigurationIConfigurationRefresher 注入 Worker 服务,并记录应用程序配置中的配置数据。

    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        private readonly IConfiguration _configuration;
        private readonly IConfigurationRefresher _refresher;
    
        public Worker(ILogger<Worker> logger, IConfiguration configuration, IConfigurationRefresher refresher)
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
            _refresher = refresher ?? throw new ArgumentNullException(nameof(refresher));
        }
    
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                // Intentionally not await TryRefreshAsync to avoid blocking the execution.
                _refresher.TryRefreshAsync(stoppingToken);
    
                if (_logger.IsEnabled(LogLevel.Information))
                {
                    _logger.LogInformation(_configuration["TestApp:Settings:Message"] ?? "No data.");
                }
    
                await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
            }
        }
    }
    

    单独调用 ConfigureRefresh 方法不会自动刷新配置。 从接口 IConfigurationRefresher 调用 TryRefreshAsync 方法以触发刷新。 此设计旨在避免请求发送到应用配置(即使应用程序处于空闲状态)。 你可在你认为应用程序处于活动状态的位置包含 TryRefreshAsync 调用。 例如,可以是在处理传入消息、订单或复杂任务迭代时。 如果应用程序始终处于活动状态,则也可以是在计时器中。 在此示例中,每次执行后台服务时都会调用 TryRefreshAsync。 请注意,即使调用 TryRefreshAsync 因任何原因而失败,应用程序也将继续使用缓存的配置。 当配置的缓存过期时间已过,并且应用程序活动再次触发 TryRefreshAsync 调用时,将进行另一次尝试。 在配置的缓存过期时间过去之前调用 TryRefreshAsync 是一个空操作,因此,即使频繁调用,它的性能影响也很小。

在本地生成并运行应用

  1. 设置环境变量。

    将名为 Endpoint 的环境变量设置为 Azure 门户中存储的概述下的应用程序配置存储区的终结点。

    如果使用 Windows 命令提示符,则请运行以下命令并重启命令提示符,这样更改才会生效:

    setx Endpoint "<endpoint-of-your-app-configuration-store>"
    

    如果使用 PowerShell,请运行以下命令:

    $Env:Endpoint = "<endpoint-of-your-app-configuration-store>"
    

    如果使用 macOS 或 Linux,则请运行以下命令:

    export Endpoint='<endpoint-of-your-app-configuration-store>'
    
  2. 运行以下命令以生成应用。

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

    dotnet run
    
  4. 控制台中应会显示以下输出。

    屏幕截图显示了后台服务。

  5. 在 Azure 门户中,导航到应用程序配置存储区的“配置资源管理器”,并更新以下键的值。

    TestApp:Settings:Message Azure 应用配置的数据 - 已更新
  6. 等待刷新间隔时间窗口过去。 你将会看到控制台输出已更改。

    屏幕截图显示了刷新的后台服务。

清理资源

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

重要

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

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

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

后续步骤

在本教程中,你已启用 .NET 后台应用,以通过应用程序配置动态刷新配置设置。 若要了解如何在 ASP.NET Web 应用程序中实现动态配置,请继续学习下一篇教程:

若要了解如何使用 Azure 托管标识来简化对应用程序配置的访问,请继续学习下一篇教程: