.NET Core etcd 配置源
etcd 是一個(gè)高可用的 Key/Value 存儲(chǔ)系統(tǒng),主要用于共享配置和服務(wù)發(fā)現(xiàn),和目前比較主流的配置中心(如:Spring Cloud Config、Apollo、Consul、Nacos)、注冊(cè)中心(如:Zookeeper、Eureka、Consul、Nacos)功能上有很多相似之處,關(guān)于各框架之間的對(duì)比可以網(wǎng)上搜索。
ectd 的搭建不是本文的重點(diǎn),本文將基于 ectd v3 版本來測試,為了方便查看效果,還將借助 ?etcd-manage 可視化管理工具。
etcd 客戶端
既然程序需要獲取 etcd 中的配置信息,那就必須有對(duì) etcd 操作的客戶端代碼。官方提供了調(diào)用 etcd 服務(wù)的 gRPC 接口定義,而 gRPC 有一個(gè)特點(diǎn)就是跨語言,所以如果項(xiàng)目中需要引入 etcd 作為配置或注冊(cè)中心,完全可以直接基于 gRPC 接口定義文件生成對(duì)應(yīng)語言的客戶端代碼實(shí)現(xiàn)遠(yuǎn)程調(diào)用。而對(duì)于目前來說,客戶端代碼的封裝在 Github 上早已有實(shí)現(xiàn),如:Java 的 jetcd,.NET 的 dotnet-etcd ,所以我們完全可以站在巨人的肩膀上玩耍。
.NET Core 集成 etcd
關(guān)于如何在 .NET 中操作 etcd ,我們可以根據(jù) dotnet-etcd 的介紹來進(jìn)行一系列測試,本文主要介紹 .NET Core 基于 etcd 實(shí)現(xiàn)服務(wù)的配置管理。既然客戶端代碼有現(xiàn)成的,那是不是直接 NuGet 安裝 dotnet-etcd 后,通過方法調(diào)用拿到某些 key 的值使用就好了?當(dāng)然這么玩沒有任何問題,但個(gè)人感覺這樣在程序上看來有些松散,畢竟 .NET Core 有可擴(kuò)展性的配置體系,最終都通過 ConfigurationBuilder 構(gòu)造供使用。
基于上篇文章 .NET Core 自定義配置源 的介紹,接下來將使用 etcd 作為自定義配置源,所以為了接下來理解順利,請(qǐng) 務(wù)必閱讀 過 ?.NET Core 自定義配置源 。
實(shí)現(xiàn)目標(biāo)
可通過 Configuration 對(duì)象進(jìn)行配置信息讀取;
etcd 配置中心對(duì)相關(guān)配置進(jìn)行變更時(shí),能自動(dòng)刷新配置;
前面提到了 etcd 是一個(gè) Key/Value 存儲(chǔ)系統(tǒng),我們可以指定 完整 key ?或 key 前綴 來獲取配置信息,下面將基于 /namespance1/ 這個(gè)前綴進(jìn)行獲取并監(jiān)聽變更來演示效果。
etcd-manage
獲取 etcd 配置數(shù)據(jù)源
定義接口 IConfigrationWatcher,含 FireChange 方法,這里定義的比較簡單,只在配置發(fā)生變更時(shí)發(fā)出一個(gè)信號(hào),所以是 void 類型,但如果要實(shí)現(xiàn)對(duì)特定 key 變更進(jìn)行增量處理也是可以的。
public interface IConfigrationWatcher {void FireChange(); }定義接口 IConfigrationRepository,包含 GetConfig 和 Watch 兩個(gè)方法。
GetConfig 實(shí)現(xiàn)根據(jù)指定的前綴從 ectd 獲取配置,轉(zhuǎn)換成 IDictionary<string, string> 返回。
Watch 則監(jiān)聽配置變更,當(dāng)發(fā)生變更時(shí),調(diào)用 IConfigrationWatcher 對(duì)象的 FireChange 方法。
完整實(shí)現(xiàn)代碼:EtcdConfigurationRepository.cs,主要使用到 dotnet-etcd 中的 GetRange 和 WatchRange,WatchRange 的實(shí)現(xiàn)是基于 gRPC 的雙向流模式,變更通知可以理解為是實(shí)時(shí)的。
實(shí)現(xiàn) EtcdConfigurationProvider
EtcdConfigurationProvider 的實(shí)現(xiàn)和之前的介紹類似,區(qū)別在于這里將使用到父類 ConfigurationProvider 的 GetReloadToken 和 OnReload 方法,構(gòu)造函數(shù)中通過 ChangeToken.OnChange 對(duì) ReloadToken 進(jìn)行狀態(tài)變更監(jiān)聽。
IConfigrationWatcher 的 ?FireChange 觸發(fā) OnReload,OnReload 觸發(fā) ChangeToken 的狀態(tài)變化,ChangeToken 的狀態(tài)變化觸發(fā) Load 方法重新執(zhí)行,Data 屬性被重新賦值。
注:需不需要 Reload 可通過 reloadOnChange 參數(shù)自定義
public class EtcdConfigurationProvider : ConfigurationProvider, IConfigrationWatcher {private readonly IConfigrationRepository _configRepository;public EtcdConfigurationProvider(IConfigrationRepository configRepository, bool reloadOnChange){_configRepository = configRepository;if (reloadOnChange){_configRepository.Watch(this);ChangeToken.OnChange(() => GetReloadToken(),() => Load());}}public override void Load(){Data = _configRepository.GetConfig();}public void FireChange() => OnReload(); }EtcdConfigurationSource 則返回 EtcdConfigurationProvider 對(duì)象即可,最后定義 IConfigurationBuilder 擴(kuò)展方法 AddEtcd 供使用。完整代碼請(qǐng)參考:Etcd.Configuration
測試效果
appsettings.json 增加 etcd 相關(guān)配置參數(shù):
"etcd": {"connectionString": "http://localhost:2379","prefixKeys": ["/namespace1/"],"keyMode": 1 // json 格式 : 分隔 }Program.cs 增加 AddEtcd
public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.ConfigureAppConfiguration(builder =>{builder.AddEtcd(builder.Build().GetSection("etcd"), true);});webBuilder.UseStartup<Startup>();});Startup.cs 的 Configuration 對(duì)象中 EtcdConfigurationProvider Data 數(shù)據(jù)如下:
etcd data
基于這樣的數(shù)據(jù)格式,可以將其注入到 Namespace1Options 實(shí)體上,然后在程序中直接使用 Namespace1Options:
public class Namespace1Options {public string Name { get; set; }public string Company { get; set; } }Startup.cs 的 ConfigureServices 方法中添加如下代碼:
services.Configure<Namespace1Options>(Configuration.GetSection("/namespace1/"));使用 Namespace1Options :
public class WeatherForecastController : ControllerBase {private readonly Namespace1Options _options;public WeatherForecastController(IOptionsSnapshot<Namespace1Options> options){_options = options.Value;}[HttpGet]public ActionResult<IEnumerable<string>> Get(){return new string[] { _options.Name, _options.Company };} }etcd 中對(duì) company 值就行修改,在不重啟服務(wù)情況下,馬上生效。
result
參考鏈接:
.NET Core 自定義配置源
dotnet-etcd
etcd-manage
Etcd.Configuration
總結(jié)
以上是生活随笔為你收集整理的.NET Core etcd 配置源的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软面向初学者的机器学习课程:3.1-构
- 下一篇: 如何排查 .NET 内存泄漏