动态 ASP.NET 核心配置 🗒️ 跟 Consul KV(干货)
背景
通常,.NET 和 .NET Core 应用程序中的配置存储在配置文件中,例如 App.config 和 Web.config,或 appsettings.json;但是,它们都有一些缺点。
- 硬编码的配置文件
- 难以管理
例如,如果由于某些原因我们需要频繁更改配置文件,那么我们如何解决这个问题?如果有很多机器,我们无法一一修改它们!
在本文中,我将介绍使用Consul KV存储的三种方法。
什么是领事

Consul 是一种分布式、高可用性和数据中心感知型解决方案,用于跨动态的分布式基础架构连接和配置应用程序。
我们将使用其名为键/值存储的功能之一。它是一个灵活的键/值存储,可以存储动态配置、功能标记、协调、领导者选举等。简单的 HTTP API 使其易于在任何地方使用。
直接调用 REST API
通过这种方式,我们通过 REST API 从 Consul KV 存储中读取配置。我们需要在项目中配置的是领事的地址。
首先创建一个 ASP.NET 核心 Web API 项目。
在这里,我们将使用一个名为 Consul 的包来处理 REST API,这可以简化它!
通过 NuGet 添加领事包。
- Install-Package Consul -Version 0.7.2.6
- {
- "Logging": {
- "LogLevel": {
- "Default": "Warning"
- }
- },
- "AllowedHosts": "*",
- "Consul": {
- "Host": "http://127.0.0.1:8500"
- }
- }
- public static IServiceCollection AddConsul(this IServiceCollection services, IConfiguration configuration)
- {
- services.AddSingleton<IConsulClient, ConsulClient>(p => new ConsulClient(consulConfig =>
- {
- //consul address
- var address = configuration["Consul:Host"];
- consulConfig.Address = new Uri(address);
- }, null, handlerOverride =>
- {
- //disable proxy of httpclienthandler
- handlerOverride.Proxy = null;
- handlerOverride.UseProxy = false;
- }));
- return services;
- }
以下代码演示如何在控制器中使用它。
- [Route("api/[controller]")]
- [ApiController]
- public class ValuesController : ControllerBase
- {
- private readonly IConsulClient _consulClient;
- public ValuesController(IConsulClient consulClient)
- {
- this._consulClient = consulClient;
- }
- [HttpGet("")]
- public async Task<string> GetAsync([FromQuery]string key)
- {
- var str = string.Empty;
- //query the value
- var res = await _consulClient.KV.Get(key);
- if (res.StatusCode == System.Net.HttpStatusCode.OK)
- {
- //convert byte[] to string
- str = System.Text.Encoding.UTF8.GetString(res.Response.Value);
- }
- return $"value-{str}";
- }
- }
让我们来看看结果。
在 Consul KV 中添加密钥之前,我们无法获取该值。
创建和修改后,我们可以实时获取最新值。
但是,这种方式无法与 ASP.NET 核心提供的配置系统结合使用。在下一节中,我将介绍如何与 ASP.NET Core的配置相结合。
与配置系统相结合
大多数时候,我们使用 IConfiguration、IOptions<T>、IOptionsSnapshot<T> 和 IOptionsMonitor<T> 来读取 ASP.NET Core 中的配置。我们如何将它们与领事结合起来?
在这里,我建议使用Winton.Extensions.Configuration.Consul。这是一个了不起的项目,它增加了对使用 Consul 配置 .NET Core 应用程序的支持。
由于使用了这个项目,事情会变得更容易!它可以帮助我们读取和重新加载领事KV中的配置。
让我们来看看如何做到这一点。
首先通过 NuGet 安装此包。
- Install-Package Winton.Extensions.Configuration.Consul -Version 2.1.2
在我们配置领事之前做好准备。
创建一个显示选项用法的设置类。
- public class DemoAppSettings
- {
- public string Key1 { get; set; }
- public string Key2 { get; set; }
- }
在启动类中配置选项:
- public void ConfigureServices(IServiceCollection services)
- {
- services.Configure<DemoAppSettings>(Configuration.GetSection("DemoAppSettings"));
- services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
- }
注意
我们不需要修改appsettings.json文件。
在控制器中调用配置。
- [Route("api/[controller]")]
- [ApiController]
- public class ValuesController : ControllerBase
- {
- private readonly IConfiguration _configuration;
- private readonly DemoAppSettings _options;
- private readonly DemoAppSettings _optionsSnapshot;
- public ValuesController(
- IConfiguration configuration
- , IOptions<DemoAppSettings> options
- , IOptionsSnapshot<DemoAppSettings> optionsSnapshot)
- {
- this._configuration = configuration;
- this._options = options.Value;
- this._optionsSnapshot = optionsSnapshot.Value;
- }
- // GET api/values
- [HttpGet]
- public ActionResult<IEnumerable<string>> Get()
- {
- return new string[] {_configuration["DemoAppSettings:Key1"], _options.Key1, _optionsSnapshot.Key1 };
- }
- }
最后,我们应该配置 Winton.Extensions.Configuration.Consul。它提供了两种方法,一种是在程序类中,另一种是在启动类中。
下面的代码演示如何在程序类中进行配置。
- public static void Main(string[] args)
- {
- var cancellationTokenSource = new CancellationTokenSource();
- WebHost
- .CreateDefaultBuilder(args)
- .ConfigureAppConfiguration(
- (hostingContext, builder) =>
- {
- builder
- .AddConsul(
- "App1/appsettings.json",
- cancellationTokenSource.Token,
- options =>
- {
- options.ConsulConfigurationOptions =
- cco => { cco.Address = new Uri("http://127.0.0.1:8500"); };
- options.Optional = true;
- options.ReloadOnChange = true;
- options.OnLoadException = exceptionContext => { exceptionContext.Ignore = true; };
- })
- .AddEnvironmentVariables();
- })
- .UseStartup<Startup>()
- .Build()
- .Run();
- cancellationTokenSource.Cancel();
- }
这是运行此项目后的结果。
我们在领事中创建了一个KV,并访问了 http://localhost:5000/api/values。我们可以从领事那里读取配置。
After modifying key1's value from 1111 to 1122, refresh the browser; the values were changed but IOptions<DemoAppSettings>.

因此,当我们使用这种方式来处理配置时,我们不应该在我们的代码中使用IOptions<T>!这是一个重要的提示。
还有另一种动态配置的方法。
领事模板
Consul 模板是一个组件,它提供了一种将 Consul 中的值填充到文件系统中的便捷方法。
欲了解更多信息,请访问其GITHUB页面
大多数情况下,appsettings.json,appsettings.xml,appsettings或其他文件中的配置是硬编码的.ini但是,我们可以利用Consul的KV存储来避免文件中的硬编码配置,因此如果应用程序设置中需要任何修改,我们不必每次都更改文件。
这些文件更新应由 Consul 工具完成。我们可以替换任何文件而不是此 JSON 文件,因为该过程对所有文件的工作方式相同。
下图显示了如何执行此操作。
首先创建一个 ASP.NET 核心 Web API 项目。
这是像以前一样的东西。
- public class DemoAppSettings
- {
- public string Key1 { get; set; }
- public string Key2 { get; set; }
- }
- public class Startup
- {
- public void ConfigureServices(IServiceCollection services)
- {
- //config
- services.Configure<DemoAppSettings>(Configuration.GetSection("DemoAppSettings"));
- services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
- }
- }
- [Route("api/[controller]")]
- [ApiController]
- public class ValuesController : ControllerBase
- {
- private readonly IConfiguration _configuration;
- private readonly DemoAppSettings _options;
- private readonly DemoAppSettings _optionsSnapshot;
- public ValuesController(IConfiguration configuration, IOptions<DemoAppSettings> options, IOptionsSnapshot<DemoAppSettings> optionsSnapshot)
- {
- this._configuration = configuration;
- this._options = options.Value;
- this._optionsSnapshot = optionsSnapshot.Value;
- }
- // GET api/values
- [HttpGet]
- public ActionResult<IEnumerable<string>> Get()
- {
- //to show the result of different usges
- return new string[] { _configuration["DemoAppSettings:Key1"], _options.Key1, _optionsSnapshot.Key1 };
- }
- }
创建配置文件
创建一个配置文件,告诉“consul-template”源文件名和目标文件名。
“consul-template”将读取配置,并通过从 Consul 的键值存储中添加模板文件中引用的值来转换模板文件,并为应用程序生成配置文件。
在这里,我们创建一个名为“appsettings.tpl”的配置文件,其内容如下。
- {{ key "App1/appsettings.json" }}
启动领事模板,
- consul-template -template "yourpath/appsettings.tpl:yourpath/appsettings.json"
这是结果。
在 Consul KV 中修改值后,appsettings.json 被实时更改。

访问浏览器的行为与第二种方式相同。
总结
本文向您展示了使用 Consul KV 进行动态 ASP.NET 核心项目配置的三种方法。
- 直接调用 REST API
- Winton.Extensions.Configuration.Consul
- 领事模板
我建议你使用第二种和第三种方式。因为这两种方式更容易。
希望对您有所帮助!
相关文章
浙公网安备 33010602011771号