Net Core自定义配置源从配置中心读取配置
前言
配置,几乎所有的应用都离不开它。在……的时代。Net框架,我们使用了App.config和Web.config,在。Net Core,我们使用了我们熟悉的appsettings.json。然而,在容器化和微服务时代,这些本地文件配置有时是不合适的。当您将本地部署的服务移动到docker时,您会发现修改配置文件非常麻烦。您必须通过主机进入容器才能修改文件。可能容器里没有vi之类的编辑工具,你连看都看不到,也改不了。更不要说在启动多个容器实例做分布式应用的时候,一个个修改容器的配置,这绝对是致命的。
基于这些原因,“配置中心”诞生了。配置中心是微服务的基础设施,集中管理配置并对外公开接口,在应用需要时通过接口读取。配置通常处于键/值模式,然后通过http接口公开。好了,关于配置中心我就不多说了。我觉得有偏见。这次,我将介绍如何自定义配置源,以便从配置中心读取配置。废话少说,直接进入代码。
模拟配置中心
我们在ASP.NET新建了一个Core Web API站点来模拟配置中心服务,并将端口配置为5000,并添加相应的控制器来模拟配置中心的外部接口。
[Route(' API/[controller]')][API controller]公共类configs controller : controller base { public listbyvaluepairstring,string Get(){ var configs=new listbyvaluepairstring,string();配置。添加(新的KeyValuePairstring,string('SecretKey ',' 1238918290381923 ');配置。添加(新的KeyValuePairstring,string('ConnectionString ',' user=123密码=123;服务器='));返回配置;}}添加一个configscontroller并修改Get方法以返回两个配置键值对。
访问/api/configs查看返回是否正确
自定义配置源
从现在开始,我们真正开始定义一个自定义的配置源,然后在程序启动时从配置中心读取配置文件信息,并提供给下面的代码使用配置。
创建一个新的ASP.NET核心MVC站点来模拟客户端程序。
我的配置提供程序
public class my config provider :配置提供程序{///summary///尝试从远程配置中心////summary public async override void load(){ var response=' ' }读取配置信息;请尝试{ var serverAddress=' http://localhost :5000 ';var client=new Httpclient();客户。BaseAddress=新的Uri(ServerAddress);响应=等待客户端。GetStringAsync('/API/configs ');} catch(Exception ex){//写入err log } if(字符串。IsNullOrEmpty(响应)){引发新异常('无法从远程配置中心请求配置。');} var configs=JsonConvert。反序列化对象列表键值对字符串,字符串(响应);data=new concurrentdictionary string,string();配置。ForEach(c={ Data。添加(c);});}}创建一个新的MyConfigProvider类,该类继承自ConfigurationProvider,并覆盖其中的Load方法。使用HttpClient从配置中心读取信息后,将其反序列化,并将配置转换为字典。这里要注意的是,虽然Data的类型是IDictionarystring,string,但是在这里实例化对象的时候使用了类ConcurrentDictionarystring,string,因为Dictionarystring,string是非线程安全的,如果用多线程读写会出现问题。
MyConfigSource
公共类myconfiggsource : iconfightource { public iconfightionprovider Build(iconfightionbuilder){ return new myconfigingprovider();}}创建一个新的IConfigurationSource类,实现MyConfigSource接口。IConfigurationSource接口只有一个Build方法,返回值为IConfigurationProvider。我们刚刚定义的my ConfigurationProvider已经实现了iConfigurationProvider,因为它继承了configuration provider,所以我们直接创建一个my configuration provider并返回它。
MyConfigBuilderExt
公共静态类MyConfigBuilderExt {公共静态iconfigulationbuilder AddMyConfig(此iconfigulationbuilder){ return builder。添加(新的MyConfigSource());}}为IConfigurationBuilder定义一个AddMyConfig的扩展方法,与带来的几个配置源的使用风格一致。网络核心。调用AddMyConfig时,将MyConfigSource的源添加到IConfigurationBuilder实例。
使用配置源
将我的配置资源添加到程序中
公共类程序{ public static void Main(string[]args){ CreateWebHostBuilder(args)。构建()。run();}公共静态IWebHostBuilder CreateWebHostBuilder(字符串[]参数)=WebHost。CreateDefaultBuilder(args)。ConfigureAppConfiguration((上下文,config builder)={ config builder。AddMyConfig();}) .UseStartupStartup();}在ConfigureAppConfiguration的匿名委托方法中调用AddMyConfig扩展方法,这样当程序启动时,它将自动使用MyConfigSource源,并将配置从配置中心读取到本地应用程序。
修改家庭控制器
公共类HomeController :控制器{ icon configuration _ configuration;公共HomeController(icon configuration配置){ _ configuration=configuration} public IActionResult Index(){ var secretKey=_ configuration[' secretKey '];var connectionString=_ configuration[' connectionString '];视图包。SecretKey=secretKey视图包。ConnectionString=ConnectionString;返回视图();}}修改homecontroller,通过构造函数将IConfiguration注入其中,读取Index Action方法中的配置,赋给ViewBag
修改索引视图
@{视图数据['标题']='测试我的配置';} h3secretkey 3360 @ ViewBag.secretkey/h3h3connectionstring: @ viewbag . connectionstring/H3修改Index视图的代码,从viewpag中读取配置信息并显示在网页上。
运行它
首先运行配置中心网站,然后运行该网站。配置中心定义的SecretKey和ConnectionString信息出现在主页上,表示我们的程序成功地从配置中心读取了配置信息。我们的自定义配置源已成功运行。
改进
虽然上面的配置源可以成功运行,但是如果仔细看,显然有两大问题。
配置中心的服务地址写在类中。我们的配置中心很可能会修改ip或者域名,所以写在代码里显然不聪明,所以我们还是需要保留本地配置文件,把配置中心的服务地址写在本地配置文件里。作为微服务基础设施的配置中心一旦出现故障,将导致非常严重的后果,新启动或重启的客户端将无法正常启动。如果我们在配置中心正常的时候在本地有一个冗余配置,在配置中心出现故障的时候在本地读取配置,至少有一部分客户端程序可以正常运行。{ ' logging ' : { ' log level ' : { ' default ' : ' warning ' },' allowed hosts' :' * ',myconfigServer ' 3360 ' http://localhost 33605000 ' }修改本地appsettings.
公共类MyConfigProvider : configuration provider { private string _ serverAddress;public myonconfigprovider(){ var jsonConfig=new JsonConfigurationSource();jsonConfig。文件提供程序=新的物理文件提供程序(目录。GetCurrentDirectory());jsonConfig。Path=' appsettings.jsonvar jsonProvider=new JsonConfigurationProvider(jsonConfig);jsonProvider。load();jsonProvider。TryGet('myconfigServer ',out字符串服务器地址);if(字符串。IsNullOrEmpty(serverAddress)) {引发新异常('无法从appsettings.json找到myconfigServer的地址');} _服务器地址=服务器地址;}///summary////尝试从远程配置中心读取配置信息,当从配置中心成功读取信息时,将配置写入本地myconfig.json文件,当配置中心不可访问时,尝试从本地文件恢复配置。////摘要公共异步覆盖void Load(){ var response=' ';尝试{ var client=new Httpclient();客户。BaseAddress=新的Uri(_ ServerAddress);响应=等待客户端。GetStringAsync('/API/configs ');WriteToLocal(响应);} catch(Exception ex){//write err log response=readfromLocal();} if(字符串。IsNullOrEmpty(响应)){引发新异常('无法从远程配置中心请求配置。');} var configs=JsonConvert。反序列化对象列表键值对字符串,字符串(响应);data=new concurrentdictionary string,string();配置。ForEach(c={ Data。添加(c);});} private void WriteToLocal(字符串resp) { var file=Directory。GetCurrentDirectory()'/my config . JSON ';文件。WriteAllText(文件,分别);}私有字符串readfromLocal(){ var file=Directory。GetCurrentDirectory()'/my config . JSON ';返回文件。ReadAllText(文件);}}通过JsonConfigurationProvider在本地修改MyConfigProvider,修改构造函数,读取appsettings.json中的myconfigServer配置信息。添加WriteToLocal方法,将配置中心返回的json数据写入本地文件。添加ReadFromLocal方法从本地文件中读取json信息。
再跑一次
先运行配置中心网站,再运行客户端网站,可以看到首页界面显示的配置信息。关闭配置中心的客户端和客户端网站,重新启动客户端网站,仍然可以显示配置信息,表示配置中心失败时,自定义配置源成功从本地文件恢复配置。图片与上图一致,不再贴出。
摘要
通过以上,我们定义了一个简单的自定义配置源,它可以通过http从配置中心读取配置,并提供与传统json配置文件相同的使用风格,最大限度地重用旧代码,减少配置中心的引入带来的大规模代码更改。从上面的代码中,我们可以更清楚地知道。网络核心工程。配置源只是配置提供者的构建者。真正完成配置加载和搜索的是配置提供者。
以上代码还是演示级代码,还有很大的改进空间,比如重试http访问失败,我们可以用polly重构;比如有兴趣可以自己练习。
好了,这就是本文的全部内容。希望本文的内容对你的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。
版权声明:Net Core自定义配置源从配置中心读取配置是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。