概念
什麼是配置中心
配置是用來動態修改程序執行的一種行爲的機制,實現熱更新
爲什麼要使用配置中心
安全性:配置跟隨源代碼保存在代碼庫中,容易造成配置泄漏。
時效性:修改配置,需要重啓服務才能生效。
侷限性:無法支持動態調整:例如日誌開關、功能開關。
因此,分佈式配置中心應運而生!
現階段主流的配置中心類型
Apollo,java開發 ----- 運維成本比高 Apollo分爲MySQL,Config Service,Admin Service,Portal四個模塊,MySQL存儲Apollo元數據和用戶配置數據; Config Service提供配置的讀取、推送等功能,客戶端請求都是落到Config Service上; Admin Service提供配置的修改、發佈等功能,Portal操作的服務就是Admin Service; Portal提供給用戶配置管理界面;功能強大,社區活躍,但較爲複雜,部署組件較多,運維成本比高 Consul, go開發 依賴:不依賴其他組件 應用內/外:屬於外部應用,侵入性小 ACP原則:遵循CP原則(一致性+分離容忍) 服務註冊稍慢,由於其一致性導致了在Leader掛掉時重新選舉期間真個consul不可用。 版本迭代:目前仍然進行版本迭代 集成支持:支持SpringCloud K8S集成 訪問協議:HTTP/DNS 雪崩保護:不支持雪崩保護 集成:SpringCloud集成,K8S集成 自動註銷實例:不支持 界面:英文界面,不符合國人習慣 上手:複雜一點 Nacos,依賴:mysql ----- 依賴:mysql 應用內/外:屬於外部應用,侵入性小 ACP原則:通知遵循CP原則(一致性+分離容忍) 和AP原則(可用性+分離容忍) 版本迭代:目前仍然進行版本迭代,最近的提交是幾天前 集成支持:支持Dubbo 、SpringCloud、K8S集成 訪問協議:HTTP/動態DNS/UDP 雪崩保護:支持雪崩保護 Spring cloud config java開發 ----- Net支持比較差 自動註銷實例:支持 界面:國產服務,中文界面,符合國人習慣 上手:極易,中文文檔,案例,社區活躍 Consul實際上是和Nacos比較相似的產品,雖然Consul目前的主要發展方向放在了Service Mesh,但是Consul最初支持的服務發現和配置管理,也是Nacos的兩大功能。雖然Nacos在Consul之後以與之相似的部署架構開源,但這並不意味着Nacos在功能和架構上也模仿Consul,Nacos的架構和功能是由阿里巴巴內部十年的運行演進經驗得來,所以二者的比較也一定會讓大家更加了解他們的定位和演進方向是完全不一樣的。
Consul 配置中心示例
單服務單個配置文件
1. Nuget引入包
Winton.Extensions.Configuration.Consul
2. Program文件中配置
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.ConfigureAppConfiguration((hostingContext, config) => { // 加載默認配置信息到Configuration hostingContext.Configuration = config.Build(); // 加載consul配置中心配置 //string consul_url = hostingContext.Configuration["Consul_Url"]; string consul_url = "http://localhost:8500"; config.AddConsul( "appsettings.json", options => { options.ConsulConfigurationOptions = cco => { cco.Address = new Uri(consul_url); }; // 1、consul地址 options.Optional = true; // 2、配置選項 options.ReloadOnChange = true; // 3、配置文件更新後重新加載 options.OnLoadException = exceptionContext => { exceptionContext.Ignore = true; }; // 4、忽略異常 } ); // 5、consul中加載的配置信息加載到Configuration對象,然後通過Configuration 對象加載項目中 hostingContext.Configuration = config.Build(); }); webBuilder.UseStartup<Startup>(); });
3. 在Consul客戶端中新增一個key爲 appsettings.json 的Json文件,將我們項目中的 appsettings.json 文件內容拷貝進去
4. 在項目中新建一個讀取配置的接口,方便測試,讀取配置文件中key爲 test_name 的值
/// <summary> /// 測試配置中心 /// </summary> /// <returns></returns> [HttpGet("TestConfiguration")] public async Task<IActionResult> TestConfiguration() { return Ok($"當前配置的name是:{_configuration.GetSection("test_name")?.Value}"); }
運行測試一下,
在consul客戶端中修改配置文件中的值 ,不用重啓項目,再次運行
多服務單個配置文件
這裏的key 命名方式就是 : {服務名稱}/appsettings.json 。 或者 {服務名稱}/appsettings.{環境名稱}.json
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.ConfigureAppConfiguration((hostingContext, config) => { #region 2. 多服務單配置 // 加載默認配置信息到Configuration hostingContext.Configuration = config.Build(); // 加載consul配置中心配置 ////string consul_url = hostingContext.Configuration["Consul_Url"]; string consul_url = "http://localhost:8500"; // 動態加載環境信息,主要在於動態獲取服務名稱和環境名稱 var env = hostingContext.HostingEnvironment; config.AddConsul( // $"{env.ApplicationName}/appsettings.{env.EnvironmentName}.json", $"{env.ApplicationName}/appsettings.json", options => { options.ConsulConfigurationOptions = cco => { cco.Address = new Uri(consul_url); }; // 1、consul地址 options.Optional = true; // 2、配置選項 options.ReloadOnChange = true; // 3、配置文件更新後重新加載 options.OnLoadException = exceptionContext => { exceptionContext.Ignore = true; }; // 4、忽略異常 } ); // 5、consul中加載的配置信息加載到Configuration對象,然後通過Configuration 對象加載項目中 hostingContext.Configuration = config.Build(); #endregion }); webBuilder.UseStartup<Startup>(); });
多服務多個配置文件
每個服務可能還有多個配置文件或者共用的一個配置文件。這裏我就在特定的服務裏面新加一個自定義的配置文件和一個所有服務共用的配置文件
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.ConfigureAppConfiguration((hostingContext, config) => { #region 3. 多服務多配置 // 加載默認配置信息到Configuration hostingContext.Configuration = config.Build(); // 加載consul配置中心配置 ////string consul_url = hostingContext.Configuration["Consul_Url"]; string consul_url = "http://localhost:8500"; // 動態加載環境信息,主要在於動態獲取服務名稱和環境名稱 var env = hostingContext.HostingEnvironment; config.AddConsul( // $"{env.ApplicationName}/appsettings.{env.EnvironmentName}.json", $"{env.ApplicationName}/appsettings.json", options => { options.ConsulConfigurationOptions = cco => { cco.Address = new Uri(consul_url); }; // 1、consul地址 options.Optional = true; // 2、配置選項 options.ReloadOnChange = true; // 3、配置文件更新後重新加載 options.OnLoadException = exceptionContext => { exceptionContext.Ignore = true; }; // 4、忽略異常 } ) .AddConsul( $"{env.ApplicationName}/custom.json", options => { options.ConsulConfigurationOptions = cco => { cco.Address = new Uri(consul_url); }; // 1、consul地址 options.Optional = true; // 2、配置選項 options.ReloadOnChange = true; // 3、配置文件更新後重新加載 options.OnLoadException = exceptionContext => { exceptionContext.Ignore = true; }; // 4、忽略異常 } ) .AddConsul( $"common.json", options => { options.ConsulConfigurationOptions = cco => { cco.Address = new Uri(consul_url); }; // 1、consul地址 options.Optional = true; // 2、配置選項 options.ReloadOnChange = true; // 3、配置文件更新後重新加載 options.OnLoadException = exceptionContext => { exceptionContext.Ignore = true; }; // 4、忽略異常 } ) ; // 5、consul中加載的配置信息加載到Configuration對象,然後通過Configuration 對象加載項目中 hostingContext.Configuration = config.Build(); #endregion }); webBuilder.UseStartup<Startup>(); });
在服務接口中添加測試
/// <summary> /// 測試配置中心 /// </summary> /// <returns></returns> [HttpGet("TestConfiguration")] public async Task<IActionResult> TestConfiguration() { // return Ok($"當前配置的name是:{_configuration.GetSection("test_name")?.Value}"); return Ok( @$"服務對應配置:{_configuration.GetSection("test_name")?.Value} 服務對應自定義配置:{ _configuration.GetSection("custom_name")?.Value} 共用配置:{ _configuration.GetSection("common_name")?.Value} " ); }
運行效果