Consul

关于consul的环境搭建很简单,可以用docker临时搭建以下, consul关于KV存储的api也很简单,注意/v1/kv/是默认的公共路径

-- 运行docker
docker pull consul:latest
docker run --name consul -d -p 8500:8500 consul--create  /v1/kv/是公共路径
curl  --request PUT  --data '{"host":"localhost"}'  http://127.0.0.1:8500/v1/kv/config/v1/local-- Get
curl  http://127.0.0.1:8500/v1/kv/config/v1/local-- delete
curl --request DELETE  http://127.0.0.1:8500/v1/kv/config/v1/local

在UI中看看值的内容:

Asp.net core5.0

首先说一下, 我是用vs2019创建调试好了的【虚拟机里面】, 传到git,在物理机上 用vscode打开运行, 目前感觉 vscode 还是没有vs 强大[vscode 运行时候需要输入controller  http://localhost:5000/WeatherForecast]。

asp.net的配置的基础结构依赖于 Microsoft.Extensions.Configuration.Abstractions NuGet包中的一些内容。首先,IConfigurationProvider 是用于提供配置值的接口,然后IConfigurationSource 用于提供已实现上述接口的 provider 的实例。与直接实现 IConfigurationProvider 相比,可以继承一个名为 ConfigurationProvider 的类。

1.我们的方法就是利用 HttpClient 去获取 consul 中的配置。一旦我们得到返回的数据【这里是json串】 ,我们迭代每个键值对,解码 Base64 字符串,然后展平所有键和JSON对象,以便放入字典中返回

2.我们可以使用 consul 的变更通知。通过添加一个参数(最后一个索引配置的值)来实现的,HTTP 请求会一直阻塞,直到下一次配置变更(或 HttpClient 超时),方法 ListenToConfigurationChanges,以便在后台监听 consul 的阻塞 HTTP

3.写一个 ConfigurationSource 来创建我们的 provider,以及封装一些扩展方法。

4.我们定义一个配置类 ,然后方便项目 使用

以上是我们需要实现的功能, 首先我们修改consul的内容

{"Logging": {"LogLevel": {"Default": "Warning"}},"option1": "value1_from_json","option2": 2,"subsection": {"suboption1": "subvalue1_from_json"},"student": [{"Name": "Gandalf","Age": "1000"},{"Name": "Harry","Age": "17"}],"AllowedHosts": "*","MongodbHost": {"Connection": "mongodb://127.0.0.1:27018","DataBase": "TemplateDb","Table": "CDATemplateInfo"}
}

其次 创建读取consul相关的代码[我这里是放在一起的]

using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;namespace ConsulApi
{public class ConsulConfigurationProvider : ConfigurationProvider{private const string ConsulIndexHeader = "X-Consul-Index"; //consul 的变更通知 最后一个索引配置的值private readonly string _path;private readonly HttpClient _httpClient;private readonly IReadOnlyList<Uri> _consulUrls;private readonly Task _configurationListeningTask;private int _consulUrlIndex;private int _failureCount;private int _consulConfigurationIndex;public ConsulConfigurationProvider(IEnumerable<Uri> consulUrls, string path){_path = path;_consulUrls = consulUrls.Select(u => new Uri(u, $"v1/kv/{path}")).ToList();if (_consulUrls.Count <= 0){throw new ArgumentOutOfRangeException(nameof(consulUrls));}_httpClient = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip }, true);_configurationListeningTask = new Task(ListenToConfigurationChanges);}public override void Load() => LoadAsync().ConfigureAwait(false).GetAwaiter().GetResult();private async Task LoadAsync(){Data = await ExecuteQueryAsync();if (_configurationListeningTask.Status == TaskStatus.Created)_configurationListeningTask.Start();}// consul 的变更通知private async void ListenToConfigurationChanges(){while (true){try{if (_failureCount > _consulUrls.Count){_failureCount = 0;await Task.Delay(TimeSpan.FromMinutes(1));}Data = await ExecuteQueryAsync(true);OnReload();_failureCount = 0;}catch (TaskCanceledException){_failureCount = 0;}catch{_consulUrlIndex = (_consulUrlIndex + 1) % _consulUrls.Count;_failureCount++;}}}private async Task<IDictionary<string, string>> ExecuteQueryAsync(bool isBlocking = false){//?recurse=true以递归方式查询任何节点var requestUri = isBlocking ? $"?recurse=true&index={_consulConfigurationIndex}" : "?recurse=true";using (var request = new HttpRequestMessage(HttpMethod.Get, new Uri(_consulUrls[_consulUrlIndex], requestUri)))using (var response = await _httpClient.SendAsync(request)){response.EnsureSuccessStatusCode();if (response.Headers.Contains(ConsulIndexHeader)){var indexValue = response.Headers.GetValues(ConsulIndexHeader).FirstOrDefault();int.TryParse(indexValue, out _consulConfigurationIndex);}var tokens = JToken.Parse(await response.Content.ReadAsStringAsync());List<KeyValuePair<string, JToken>> pairs=null;Dictionary<string, string> retDic = null;//我这里实际只有一个tokenint tokenCount = tokens.Count();if (tokenCount == 1){string valueStr = tokens[0].Value<string>("Value");JToken value = string.IsNullOrEmpty(valueStr) ? null : JToken.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(valueStr)));pairs = new List<KeyValuePair<string, JToken>>(1);pairs.Add(KeyValuePair.Create(string.Empty, value));}else if (tokenCount > 1) {pairs = tokens.Select(k => KeyValuePair.Create(k.Value<string>("Key").Substring(_path.Length + 1),k.Value<string>("Value") != null ? JToken.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(k.Value<string>("Value")))) : null)).Where(v => !string.IsNullOrWhiteSpace(v.Key)).ToList();}if (pairs!=null){retDic= pairs.SelectMany(Flatten).ToDictionary(v => ConfigurationPath.Combine(v.Key.Split('/')), v => v.Value, StringComparer.OrdinalIgnoreCase);}return retDic;             }}// 使键值变平的方法是对树进行简单的深度优先搜索private static IEnumerable<KeyValuePair<string, string>> Flatten(KeyValuePair<string, JToken> tuple){if (!(tuple.Value is JObject value))yield break;foreach (var property in value){var propertyKey = $"{tuple.Key}/{property.Key}";if (string.IsNullOrEmpty(tuple.Key)) {propertyKey = property.Key;}switch (property.Value.Type){case JTokenType.Object:foreach (var item in Flatten(KeyValuePair.Create(propertyKey, property.Value)))yield return item;break;case JTokenType.Array:break;default:yield return KeyValuePair.Create(propertyKey, property.Value.Value<string>());break;}}}}// 有了一个 ConfigurationProvider, 再写一个 ConfigurationSource 来创建 我们的 providepublic class ConsulConfigurationSource : IConfigurationSource{public IEnumerable<Uri> ConsulUrls { get; }public string Path { get; }public ConsulConfigurationSource(IEnumerable<Uri> consulUrls, string path){ConsulUrls = consulUrls;Path = path;}public IConfigurationProvider Build(IConfigurationBuilder builder){return new ConsulConfigurationProvider(ConsulUrls, Path);}}// 扩展方法public static class ConsulConfigurationExtensions{public static IConfigurationBuilder AddConsul(this IConfigurationBuilder configurationBuilder, IEnumerable<Uri> consulUrls, string consulPath){return configurationBuilder.Add(new ConsulConfigurationSource(consulUrls, consulPath));}public static IConfigurationBuilder AddConsul(this IConfigurationBuilder configurationBuilder, IEnumerable<string> consulUrls, string consulPath){return configurationBuilder.AddConsul(consulUrls.Select(u => new Uri(u)), consulPath);}}public class MongodbHostOptions{public string Connection { get; set; }public string DataBase { get; set; }public string Table { get; set; }}
}

3投入使用:

A:修改Program.cs 文件:

 public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureAppConfiguration(cb =>{var configuration = cb.Build();List<Uri> uris = new List<Uri>();uris.Add(new Uri("http://192.168.100.19:8500/"));cb.AddConsul( uris, "config/v1/local");}).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});

B: 修改Startup.cs文件:

  public void ConfigureServices(IServiceCollection services){services.AddControllers();services.AddOptions();services.Configure<MongodbHostOptions>(Configuration.GetSection("MongodbHost"));}

C: 修改默认的WeatherForecastController.cs

        private readonly ILogger<WeatherForecastController> _logger;MongodbHostOptions _options;public WeatherForecastController(IOptionsSnapshot<MongodbHostOptions> options ,ILogger<WeatherForecastController> logger){_logger = logger;_options = options.Value;}[HttpGet]public IEnumerable<WeatherForecast> Get(){var rng = new Random();return Enumerable.Range(1, 5).Select(index => new WeatherForecast{Date = DateTime.Now.AddDays(index),TemperatureC = rng.Next(-20, 55),Summary = Summaries[rng.Next(Summaries.Length)]+ _options.Connection}).ToArray();}

运行效果【如果consul内容跟新后,读取的也是最新数据】:

下载:https://github.com/dz45693/asp.netcoreConsulKv.git

参考:https://www.cnblogs.com/rwing/p/consul-configuration-aspnet-core.html

as.net core 5.0 Configuration读取consul的kv存储相关推荐

  1. 服务注册发现consul之四: 分布式锁之四:基于Consul的KV存储和分布式信号量实现分布式锁...

    一.基于key/value实现 我们在构建分布式系统的时候,经常需要控制对共享资源的互斥访问.这个时候我们就涉及到分布式锁(也称为全局锁)的实现,基于目前的各种工具,我们已经有了大量的实现方式,比如: ...

  2. .NET Core 6.0之读取配置文件

    在ASP.NET Core 6.0中,默认配置文件是appsettings.json,该文件存储的内容为JSON格式的字符串,我们一般都将程序的配置放在这个文件里面,提供给程序使用,那么我们该如何操作 ...

  3. .NET Core 3.0之创建基于Consul的Configuration扩展组件

    经过前面三篇关于.NET Core Configuration的文章之后,本篇文章主要讨论如何扩展一个Configuration组件出来.如果前面三篇文章没有看到,可以点击如下地址访问 .NET Co ...

  4. .NET Core 3.0之深入源码理解Configuration(一)

    微软在.NET Core里设计出了全新的配置体系,并以非常灵活.可扩展的方式实现.从其源码来看,其运行机制大致是,根据其Source,创建一个Builder实例,并会向其添加Provider,在我们使 ...

  5. 深入探究.Net Core Configuration读取配置的优先级

    前言 在之前的文章.Net Core Configuration源码探究一文中我们曾解读过Configuration的工作原理,也.Net Core Configuration Etcd数据源一文中探 ...

  6. Docker Consul Fabio ASP.NET Core 2.0 微服务跨平台实践

    相关博文: Ubuntu 简单安装 Docker Mac OS.Ubuntu 安装及使用 Consul Consul 服务注册与服务发现 Fabio 安装和简单使用 阅读目录: Docker 运行 C ...

  7. .NET Core微服务之基于Consul实现服务治理

    一.Consul基础介绍 Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,比如 Airbnb的SmartStack等相比,Co ...

  8. .NET Core微服务之基于Consul实现服务治理(续)

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 上一篇发布之后,很多人点赞和评论,不胜惶恐,这一篇把上一篇没有弄到的东西补一下,也算是给各位前来询问的朋友的一些回复吧. 一.Consul ...

  9. [译]ASP.NET Core 2.0 机密配置项

    问题 如何在ASP.NET Core 2.0中保存机密配置项(不用将其暴露给源代码管理器)? 答案 创建一个ASP.NET Core 2.0空项目,在项目节点上点击右键,并点击菜单项 - 管理用户机密 ...

最新文章

  1. 谷歌pixel3axl开发者模式_谷歌 Android Q 和 iOS 12.3新测试版发布,看完心动了!
  2. QT OpenCV Linux
  3. 测试角度的并发和幂等问题总结
  4. Java高并发编程(四):并发编程基础
  5. 用官方的SSD1306.py 驱动 OLED
  6. Node.js v7 Beta版引入citgm
  7. 《Go语言圣经》学习笔记 第五章函数
  8. (1)解锁MongoDB replica set核心姿势
  9. [delphi函数]RenameFile 文件改名
  10. Discuz!X/数据库操作方法
  11. 脸部识别算法_面部识别技术是种族主义者吗? 先进算法的解释
  12. java静态声明调用_求问 static声明的方法不是只能调用静态属性或者方法吗?
  13. php手机号最新正则表达式,最新手机号码正则表达式
  14. 手持式网络性能测试仪
  15. HTML网页媒体元素(视频音频)
  16. vue移动端用什么数据可视化插件_前端必看的数据可视化入门指南
  17. 与传统媒体相比新媒体传播所具备的特点与优势!
  18. ASP.NET访问Excel 失败的解决方法(错误号:80070005,8000401a)
  19. java开发ria是指什么_Java RIA Demo
  20. 江苏省高校微课比赛参赛经验总结

热门文章

  1. outlook 2007 激活方法
  2. 给定一个接口,测试人员应该如何测试?
  3. 初学者入门网络安全学哪种编程语言好?
  4. 什么是Socket 编程
  5. Python语句求一个正整数的全部约数
  6. android sdk 环境签名,SDK接入必备常识——keystore签名文件详解
  7. 【Vue项目实战】Vue3动画神操作!教你如何实现PPT一样的动画效果!
  8. pentaho源码分析
  9. 信号完整性之浅谈理解(七)
  10. 清华大学计算机专业的cpu,我们研制成功进入世界500强的超级计算机