新文章 网摘 文章 随笔 日记

动态 ASP.NET 核心配置 🗒️ 跟 Consul KV(干货)

 

背景

通常,.NET 和 .NET Core 应用程序中的配置存储在配置文件中,例如 App.config 和 Web.config,或 appsettings.json;但是,它们都有一些缺点。
  1. 硬编码的配置文件
  2. 难以管理
例如,如果由于某些原因我们需要频繁更改配置文件,那么我们如何解决这个问题?如果有很多机器,我们无法一一修改它们!
 
我们想要的是在“配置中心”一个地方管理配置。这里有一些很棒的项目可以帮助我们解决这个问题,例如阿波罗领事等。
 
在本文中,我将介绍使用Consul KV存储的三种方法。

什么是领事

 带领事 KV 的动态 ASP.NET 核心配置
Consul 是一种分布式、高可用性和数据中心感知型解决方案,用于跨动态的分布式基础架构连接和配置应用程序。
 
我们将使用其名为键/值存储的功能之一。它是一个灵活的键/值存储,可以存储动态配置、功能标记、协调、领导者选举等。简单的 HTTP API 使其易于在任何地方使用。
 
直接调用 REST API
 
通过这种方式,我们通过 REST API 从 Consul KV 存储中读取配置。我们需要在项目中配置的是领事的地址。
 
首先创建一个 ASP.NET 核心 Web API 项目。
 
在这里,我们将使用一个名为 Consul 的包来处理 REST API,这可以简化它!
 
通过 NuGet 添加领事包。
 
  1. Install-Package Consul -Version 0.7.2.6  
为了配置 Consul 的地址,我们需要修改appsettings.json文件。
 
  1. {  
  2.   "Logging": {  
  3.     "LogLevel": {  
  4.       "Default": "Warning"  
  5.     }  
  6.   },  
  7.   "AllowedHosts": "*",  
  8.   "Consul": {  
  9.     "Host": "http://127.0.0.1:8500"  
  10.   }  
  11. }  
配置地址后,我们应该为 Consul 添加一个扩展,这可以帮助我们使用 DI 的 ConsulClient。
 
  1. public static IServiceCollection AddConsul(this IServiceCollection services, IConfiguration configuration)  
  2. {              
  3.     services.AddSingleton<IConsulClient, ConsulClient>(p => new ConsulClient(consulConfig =>  
  4.     {  
  5.         //consul address  
  6.         var address = configuration["Consul:Host"];  
  7.         consulConfig.Address = new Uri(address);  
  8.     }, null, handlerOverride =>  
  9.     {  
  10.         //disable proxy of httpclienthandler  
  11.         handlerOverride.Proxy = null;  
  12.         handlerOverride.UseProxy = false;  
  13.     }));  
  14.     return services;  
  15. }  
接下来我们应该做的是在您需要的地方致电领事客户!
 
以下代码演示如何在控制器中使用它。
 
  1. [Route("api/[controller]")]  
  2. [ApiController]  
  3. public class ValuesController : ControllerBase  
  4. {  
  5.     private readonly IConsulClient _consulClient;  
  6.   
  7.     public ValuesController(IConsulClient consulClient)  
  8.     {  
  9.         this._consulClient = consulClient;  
  10.     }  
  11.      
  12.     [HttpGet("")]  
  13.     public async Task<string> GetAsync([FromQuery]string key)  
  14.     {  
  15.         var str = string.Empty;  
  16.         //query the value  
  17.         var res = await _consulClient.KV.Get(key);  
  18.   
  19.         if (res.StatusCode == System.Net.HttpStatusCode.OK)  
  20.         {  
  21.             //convert byte[] to string  
  22.             str = System.Text.Encoding.UTF8.GetString(res.Response.Value);  
  23.         }  
  24.   
  25.         return $"value-{str}";  
  26.     }  
  27. }  
让我们来看看结果。
 
在 Consul KV 中添加密钥之前,我们无法获取该值。
 
Dynamic ASP.NET Core Configurations With Consul KV 
 
创建和修改后,我们可以实时获取最新值。
 
Dynamic ASP.NET Core Configurations With 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 安装此包。
 
  1. Install-Package Winton.Extensions.Configuration.Consul -Version 2.1.2  

在我们配置领事之前做好准备。

创建一个显示选项用法的设置类。
 
  1. public class DemoAppSettings  
  2. {  
  3.     public string Key1 { get; set; }  
  4.     public string Key2 { get; set; }  
  5. }  
在启动类中配置选项:
 
  1. public void ConfigureServices(IServiceCollection services)  
  2. {  
  3.     services.Configure<DemoAppSettings>(Configuration.GetSection("DemoAppSettings"));  
  4.     services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);  
  5. }  

注意
我们不需要修改appsettings.json文件。

在控制器中调用配置。
 
  1. [Route("api/[controller]")]  
  2. [ApiController]  
  3. public class ValuesController : ControllerBase  
  4. {  
  5.     private readonly IConfiguration _configuration;  
  6.     private readonly DemoAppSettings _options;  
  7.     private readonly DemoAppSettings _optionsSnapshot;  
  8.   
  9.     public ValuesController(
  10.          IConfiguration configuration
  11.          , IOptions<DemoAppSettings> options
  12.          , IOptionsSnapshot<DemoAppSettings> optionsSnapshot)  
  13.     {  
  14.         this._configuration = configuration;  
  15.         this._options = options.Value;  
  16.         this._optionsSnapshot = optionsSnapshot.Value;  
  17.     }  
  18.   
  19.     // GET api/values  
  20.     [HttpGet]  
  21.     public ActionResult<IEnumerable<string>> Get()  
  22.     {  
  23.         return new string[] {_configuration["DemoAppSettings:Key1"], _options.Key1, _optionsSnapshot.Key1 };  
  24.     }          
  25. }  

最后,我们应该配置 Winton.Extensions.Configuration.Consul。它提供了两种方法,一种是在程序类中,另一种是在启动类中。

下面的代码演示如何在程序类中进行配置。
 
  1. public static void Main(string[] args)  
  2. {  
  3.     var cancellationTokenSource = new CancellationTokenSource();  
  4.     WebHost  
  5.         .CreateDefaultBuilder(args)  
  6.         .ConfigureAppConfiguration(  
  7.             (hostingContext, builder) =>  
  8.             {  
  9.                 builder  
  10.                     .AddConsul(  
  11.                         "App1/appsettings.json",  
  12.                         cancellationTokenSource.Token,  
  13.                         options =>  
  14.                         {  
  15.                             options.ConsulConfigurationOptions =  
  16.                                 cco => { cco.Address = new Uri("http://127.0.0.1:8500"); };  
  17.                             options.Optional = true;  
  18.                             options.ReloadOnChange = true;  
  19.                             options.OnLoadException = exceptionContext => { exceptionContext.Ignore = true; };  
  20.                         })  
  21.                     .AddEnvironmentVariables();  
  22.             })  
  23.         .UseStartup<Startup>()  
  24.         .Build()  
  25.         .Run();  
  26.   
  27.     cancellationTokenSource.Cancel();  
  28. }   
这是运行此项目后的结果。
 
我们在领事中创建了一个KV,并访问了 http://localhost:5000/api/values。我们可以从领事那里读取配置。
 
Dynamic ASP.NET Core Configurations With Consul KV 
 
After modifying key1's value from 1111 to 1122, refresh the browser; the values were changed but IOptions<DemoAppSettings>
 
Dynamic ASP.NET Core Configurations With Consul KV
 
因此,当我们使用这种方式来处理配置时,我们不应该在我们的代码中使用IOptions<T>!这是一个重要的提示。
 
还有另一种动态配置的方法。

领事模板

Consul 模板是一个组件,它提供了一种将 Consul 中的值填充到文件系统中的便捷方法。
 
欲了解更多信息,请访问其GITHUB页面
 
大多数情况下,appsettings.json,appsettings.xml,appsettings或其他文件中的配置是硬编码的.ini但是,我们可以利用Consul的KV存储来避免文件中的硬编码配置,因此如果应用程序设置中需要任何修改,我们不必每次都更改文件。
 
这些文件更新应由 Consul 工具完成。我们可以替换任何文件而不是此 JSON 文件,因为该过程对所有文件的工作方式相同。
 
下图显示了如何执行此操作。
 
Dynamic ASP.NET Core Configurations With Consul KV 
 
首先创建一个 ASP.NET 核心 Web API 项目。
 
这是像以前一样的东西。
 
  1. public class DemoAppSettings  
  2. {  
  3.     public string Key1 { get; set; }  
  4.     public string Key2 { get; set; }  
  5. }  
  6.   
  7. public class Startup  
  8. {  
  9.     public void ConfigureServices(IServiceCollection services)  
  10.     {  
  11.         //config   
  12.         services.Configure<DemoAppSettings>(Configuration.GetSection("DemoAppSettings"));  
  13.         services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);  
  14.     }  
  15. }  
  16.   
  17. [Route("api/[controller]")]  
  18. [ApiController]  
  19. public class ValuesController : ControllerBase  
  20. {  
  21.     private readonly IConfiguration _configuration;  
  22.     private readonly DemoAppSettings _options;  
  23.     private readonly DemoAppSettings _optionsSnapshot;  
  24.   
  25.     public ValuesController(IConfiguration configuration, IOptions<DemoAppSettings> options, IOptionsSnapshot<DemoAppSettings> optionsSnapshot)  
  26.     {  
  27.         this._configuration = configuration;  
  28.         this._options = options.Value;  
  29.         this._optionsSnapshot = optionsSnapshot.Value;  
  30.     }  
  31.   
  32.     // GET api/values  
  33.     [HttpGet]  
  34.     public ActionResult<IEnumerable<string>> Get()  
  35.     {  
  36.         //to show the result of different usges   
  37.         return new string[] { _configuration["DemoAppSettings:Key1"], _options.Key1, _optionsSnapshot.Key1 };  
  38.     }          
  39. }  
现在,我们应该转向领事模板。
 
创建配置文件
 
创建一个配置文件,告诉“consul-template”源文件名和目标文件名。
 
“consul-template”将读取配置,并通过从 Consul 的键值存储中添加模板文件中引用的值来转换模板文件,并为应用程序生成配置文件。
 
在这里,我们创建一个名为“appsettings.tpl”的配置文件,其内容如下。
 
  1. {{ key "App1/appsettings.json" }}   
启动领事模板,
 
  1. consul-template -template "yourpath/appsettings.tpl:yourpath/appsettings.json"  
这是结果。
  
Dynamic ASP.NET Core Configurations With Consul KV 
 
在 Consul KV 中修改值后,appsettings.json 被实时更改。 
 
 Dynamic ASP.NET Core Configurations With Consul KV
 
访问浏览器的行为与第二种方式相同。

总结

本文向您展示了使用 Consul KV 进行动态 ASP.NET 核心项目配置的三种方法。
  1. 直接调用 REST API
  2. Winton.Extensions.Configuration.Consul
  3. 领事模板
我建议你使用第二种和第三种方式。因为这两种方式更容易。
 
希望对您有所帮助!
 
相关文章

 

posted @ 2022-11-26 08:52  岭南春  阅读(216)  评论(0)    收藏  举报