前言

市面上已经有很多配置中心集成工具了,故此不会去实践某个框架。

下面链接是apollo 官网的教程,实在太详细了,本文介绍一下扩展数据源,和简单翻翻阅一下apollo 关键部分。

apollo 服务配置:

https://github.com/ctripcorp/apollo/wiki/.Net客户端使用指南

apollo .net 客户端配置:

https://github.com/ctripcorp/apollo.net/tree/dotnet-core/Apollo.Configuration

正文

扩展数据源

经过前面的系列的源码解读,我们知道我们需要去实现IConfigurationSource,IConfigurationProvider。

他们的关系是IConfigurationSource build 方法会构建出IConfigurationProvider,IConfigurationProvider 会为 IConfigurationRoot 提供数据源。

好的,那么开始吧。

RemoteConfigurationSource 实现 IConfigurationSource:

  1. public class RemoteConfigurationSource : IConfigurationSource
  2. {
  3. public RemoteConfigurationProvider _provider;
  4. public RemoteConfigurationProvider Provider
  5. {
  6. get
  7. {
  8. if (_provider == null)
  9. {
  10. _provider = new RemoteConfigurationProvider();
  11. }
  12. return _provider;
  13. }
  14. }
  15. public IConfigurationProvider Build(IConfigurationBuilder builder)
  16. {
  17. return this.Provider;
  18. }
  19. }

IConfigurationProvider 继承ConfigurationProvider:

  1. public class RemoteConfigurationProvider : ConfigurationProvider
  2. {
  3. public RemoteConfigurationProvider():base()
  4. {
  5. }
  6. public override void Load()
  7. {
  8. this.Data["name"] = "zhangshan";
  9. Load(false);
  10. }
  11. public void Load(bool reload)
  12. {
  13. if (reload)
  14. {
  15. this.OnReload();
  16. }
  17. }
  18. }

这里没有继承IConfigurationProvider而是继承ConfigurationProvider的原因,是因为ConfigurationProvider实现基于字典的数据源实现,这里演示比较方便。

  1. static void Main(string[] args)
  2. {
  3. IConfigurationBuilder builder = new ConfigurationBuilder();
  4. var selfSource = new RemoteConfigurationSource();
  5. builder.Add(selfSource);
  6. var root = builder.Build();
  7. Console.WriteLine($"name: {root["name"]}");
  8. ChangeToken.OnChange(() => root.GetReloadToken(), () =>
  9. {
  10. Console.WriteLine($"reload name: {root["name"]}");
  11. });
  12. selfSource.Provider.Set("name","lisi");
  13. selfSource.Provider.Load(true);
  14. Console.ReadKey();
  15. }

这里只是作为演示,实际上我们可以通过在RemoteConfigurationProvider 做监听,然后收到通知后,进行reload 调用即可,在configurationProvider中的reload如下:

  1. private ConfigurationReloadToken _reloadToken = new ConfigurationReloadToken();
  2. protected void OnReload()
  3. {
  4. ConfigurationReloadToken previousToken = Interlocked.Exchange(ref _reloadToken, new ConfigurationReloadToken());
  5. previousToken.OnReload();
  6. }

触发令牌更新,然后令牌会触发回调。

那么来看下apollo 第三方组件怎么写的吧。

引入这个包: Com.Ctrip.Framework.apollo.Configuration

  1. public class ApolloConfigurationProvider : ConfigurationProvider, IRepositoryChangeListener, IConfigurationSource
  2. {
  3. internal string? SectionKey { get; }
  4. internal IConfigRepository ConfigRepository { get; }
  5. private Task? _initializeTask;
  6. public ApolloConfigurationProvider(string? sectionKey, IConfigRepository configRepository)
  7. {
  8. SectionKey = sectionKey;
  9. ConfigRepository = configRepository;
  10. ConfigRepository.AddChangeListener(this);
  11. _initializeTask = ConfigRepository.Initialize();
  12. }
  13. public override void Load()
  14. {
  15. Interlocked.Exchange(ref _initializeTask, null)?.ConfigureAwait(false).GetAwaiter().GetResult();
  16. SetData(ConfigRepository.GetConfig());
  17. }
  18. protected virtual void SetData(Properties properties)
  19. {
  20. var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
  21. foreach (var key in properties.GetPropertyNames())
  22. {
  23. if (string.IsNullOrEmpty(SectionKey))
  24. data[key] = properties.GetProperty(key) ?? string.Empty;
  25. else
  26. data[$"{SectionKey}{ConfigurationPath.KeyDelimiter}{key}"] = properties.GetProperty(key) ?? string.Empty;
  27. }
  28. Data = data;
  29. }
  30. void IRepositoryChangeListener.OnRepositoryChange(string namespaceName, Properties newProperties)
  31. {
  32. SetData(newProperties);
  33. OnReload();
  34. }
  35. IConfigurationProvider IConfigurationSource.Build(IConfigurationBuilder builder) => this;
  36. }

里面有这个OnRepositoryChange 监听,如果收到监听信息然后就触发设置数据,然后调用OnReload 触发令牌过期,也就是触发通知。

有些人肯定问啊,肯定要有IconfigurationSource啊,在哪呢? 看这个设计ApolloConfigurationProvider 继承了IConfigurationSource接口。

ApolloConfigurationProvider实现的build(上面贴了)如下:

  1. IConfigurationProvider IConfigurationSource.Build(IConfigurationBuilder builder) => this;

直接返回本身即可。看到这里我们有时候也就不用太古板了,不是说非要分开两个类来实现。完全可以作为一个整体,也是极好的。

上述只是个人整理,如有错误,望请指点。

配置大概就整理到这里,后面写服务相关的,当然也会使用到前面这些微薄的原理(没有深入分析),就知道为什么服务配置要那么写了。

下一节 服务与配置之间。

重新整理 .net core 实践篇—————配置系统之简单配置中心[十一]的更多相关文章

  1. 重新整理 .net core 实践篇—————日志系统之战地记者[十五]

    前言 本节开始整理日志相关的东西.先整理一下日志的基本原理. 正文 首先介绍一下包: Microsoft.Extengsion.Logging.Abstrations 这个是接口包. Microsof ...

  2. 重新整理 .net core 实践篇—————日志系统之作用域[十七]

    前言 前面介绍了服务与日志之间的配置,那么我们服务会遇到下面的场景会被遇到一些打log的问题. 前面我提及到我们的log,其实是在一个队列里面,而我们的请求是在并发的,多个用户同时发送请求这个时候我们 ...

  3. 重新整理 .net core 实践篇—————日志系统之结构化[十八]

    前言 什么是结构化呢? 结构化,就是将原本没有规律的东西进行有规律话. 就比如我们学习数据结构,需要学习排序然后又要学习查询,说白了这就是一套,没有排序,谈如何查询是没有意义的,因为查询算法就是根据某 ...

  4. 重新整理 .net core 实践篇—————日志系统之服务与日志之间[十六]

    前言 前文介绍了一些基本思路,那么这里介绍一下,服务如何与配置文件配合. 正文 服务: public interface ISelfService { void ShowLog(); } public ...

  5. 重新整理 .net core 实践篇—————配置系统之强类型配置[十]

    前言 前文中我们去获取value值的时候,都是通过configurationRoot 来获取的,如configurationRoot["key"],这种形式. 这种形式有一个不好的 ...

  6. 重新整理 .net core 实践篇————配置应用[一]

    前言 本来想整理到<<重新整理.net core 计1400篇>>里面去,但是后来一想,整理 .net core 实践篇 是偏于实践,故而分开. 因为是重新整理,那么就从配置开 ...

  7. 重新整理 .net core 实践篇—————配置文件之环境配置[九]

    前言 在当今在互联网微服务比较适用的情况下,docker 可以说一个利器.每次我们打包docker的时候都是适用docker 的配置文件,那么配置文件里面会设置环境变量,这个时候需要我们的应用能够识别 ...

  8. 重新整理 .net core 实践篇————配置系统之盟约[五]

    前言 在asp .net core 中我们会看到一个appsettings.json 文件,它就是我们在服务中的各种配置,是至关重要的一部门. 不管是官方自带的服务,还是我们自己编写的服务都是用它来实 ...

  9. 重新整理 .net core 实践篇—————配置系统之军令状[七](配置文件)

    前言 介绍一下配置系统中的配置文件,很多服务的配置都写在配置文件中,也是配置系统的大头. 正文 在asp .net core 提供了下面几种配置文件格式的读取方式. Microsoft.extensi ...

随机推荐

  1. CSS 还能这样玩?奇思妙想渐变的艺术

    在之前的这篇文章 -- 一行 CSS 代码的魅力 中,我们介绍了一种使用一行 CSS 代码就能够生成的一种美妙(也许奇怪更合适)的背景. 本文,将继续介绍背景的一些有意思的知识,利用一些极小的单位,只 ...

  2. kuberadm安装kubernetes

    系统基础环境准备 环境信息 2台 Centos 7.5 cat /etc/hosts 192.168.100.101 k8s-master 192.168.103.102 k8s-node1 serv ...

  3. 深入了解Zookeeper核心原理

    之前的文章Zookeeper基础原理&应用场景详解中将Zookeeper的基本原理及其应用场景做了一个详细的介绍,虽然介绍了其底层的存储原理.如何使用Zookeeper来实现分布式锁.但是我认 ...

  4. (数据科学学习手札119)Python+Dash快速web应用开发——多页面应用

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...

  5. JMeter日志查看

  6. 7- MySQL结果数据处理与函数

    复习: 查询:select 列名 from 表 去重:distinct 排序:order by 列1 列2 排序方法:asc desc. 限定返回行数:limit n limit n,m 过滤:whe ...

  7. 让vim显示空格,tab字符,及vim多行注释

    1.显示 TAB 键 文件中有 TAB 键的时候,你是看不见的.要把它显示出来: :set list 现在 TAB 键显示为 ^I,而 $显示在每行的结尾,以便你能找到可能会被你忽略的空白字符在哪里 ...

  8. deep freeze standard v8.x

    62S93Y4Q-6C6E4EQQ-7MKMZA9F-RK5H6CSZ-AB7W3BMMPJ6GGQDCPT5EPVWGJP3EEQ5GAV2TCQD7-F8J933CA-6AEHN9ZG-2FW3M ...

  9. Day009 Arrays类

    Arrays类 数组的工具类java.util.Arrays 由于数组对象本身并没有什么方法可以供我们调用,但Api中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作. 查 ...

  10. 【我给面试官画饼】Python自动化测试面试题精讲

    那今天给家分享的是一个面试主题. 就比如说我们的自动化测试,自动化如何去应对面试官,和面试官去聊一聊自动化的心得,自动化你现在去面试的时候是一个非常重要的一个关键点,所以如果你在这方面有一定的心得.那 ...