網(wǎng)站版權(quán) 備案icp網(wǎng)絡(luò)公司名字大全
這一次我們繼續(xù)介紹微服務(wù)相關(guān)組件配置中心的使用方法。本來打算介紹下攜程開源的重型配置中心框架 apollo 但是體系實在是太過于龐大,還是讓我愛不起來。因為前面我們已經(jīng)介紹了使用Consul 做為服務(wù)注冊發(fā)現(xiàn)的組件
,那么干脆繼續(xù)使用 Consul 來作為配置中心吧。Consul 除了服務(wù)注冊發(fā)現(xiàn)功能,還有個 Key/Value 存儲的功能,我們把本地的 appsettings.json 文件的內(nèi)容搬到 Key/Value 上就可以實現(xiàn)配置中心了。
把服務(wù)的配置遷移至 Consul
讓我們來改造一下前面系列文章里的 member_center 項目,把配置文件都遷移到 consul 上面去。
?
在 consul 控制臺點擊 “Key/Value” 菜單,點擊 “create” 按鈕新建一個 Key/Value 對象。
?
Key/Value 支持按文件夾分類,當我們的 Key 以 / 結(jié)尾的時候,consul 會認為這是一個文件夾。
我們在這里輸入 “member_center/” 在創(chuàng)建文件夾。
?
在創(chuàng)建的文件夾目錄下繼續(xù)點擊 “create” 按鈕。
?
在 key 文本框里輸入 “confing.json” 。
在 Value 文本框內(nèi)把原來 appsettings.json 文件的全部內(nèi)容復制粘貼進去。
{"consul_server": "http://192.168.18.164:8500"
}
把原來 appsettings.json 文件的內(nèi)容全部刪除,只輸入一行 consul_server 的配置,用來指示 consul 服務(wù)的地址。
Install-Package Winton.Extensions.Configuration.Consul
在 member_center 項目上通過nuget安裝 Winton.Extensions.Configuration.Consul 這個組件。
public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.ConfigureAppConfiguration((ctx,cfg)=> {var localconfig = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").AddEnvironmentVariables().Build();var consul_server = localconfig["consul_server"];cfg.AddConsul("member_center/config.json",op=> {op.ConsulConfigurationOptions = cco =>{cco.Address = new Uri(consul_server);};op.ReloadOnChange = true;});});webBuilder.ConfigureKestrel(options =>{options.ListenAnyIP(6002);});webBuilder.UseStartup<Startup>();});
在 program 文件的 CreateHostBuilder 方法內(nèi)配置使用 Consul 做為配置的提供源。首先從本地讀取 consul_server 的地址。通過 AddConsul 方法指示需要從 consul 讀取的配置文件的路徑。完成以上操作后我們的服務(wù)已經(jīng)可以讀取到 Consul 存儲的配置了。
[ApiController][Route("[controller]")]public class ConsulController : ControllerBase{IConfiguration _configuration;public ConsulController(IConfiguration configuration){_configuration = configuration;}[HttpGet("getConfig")]public string GetConfig(string key){return _configuration[key];}}
我們新建一個GetConfig方法來演示下能否讀取到配置。
直接在 Controller 構(gòu)造函數(shù)注入 IConfiguration 來讀取配置,這跟我們普通本地配置的讀取方式完全一致。
http://localhost:6002/consul/getconfig?key=hotreload_test
?
在瀏覽器上訪問一下這個action對應(yīng)的url,并且指定一個key=hotreload_test,可以看到輸出的結(jié)果跟我們在 consul 上配置的值是一致的。
?
?
修改一下 consul 上面的配置值,重新讀取一下這個配置,可以看到新的值已經(jīng)被讀取到了,證明我們的熱更新也可以運行了。
把 Ocelot 網(wǎng)關(guān)的配置遷移至 Consul
上面我們演示了如何把普通服務(wù)的配置遷移至 consul,下面演示下如何把 Ocelot 的配置遷移到 Consul 上。
Ocelot 網(wǎng)站其實也就是一個 webapi 項目,本質(zhì)上跟上面的服務(wù)沒啥區(qū)別。我們根據(jù)上面的演示,其實可以很容易的把 Ocelot 項目的配置遷移到 Consul 上。那么為什么需要單獨說一下 Ocelot 網(wǎng)關(guān)的遷移呢?
本來 Ocelot 的路由配置需要把下游服務(wù)的地址跟端口在配置文件里寫死,那樣的話,我們的 Consul 服務(wù)注冊發(fā)現(xiàn)就沒有意義了,我們的下游服務(wù)都是可能動態(tài)變化的。所以我們需要讓 Ocelot 結(jié)合 Consul 的服務(wù)注冊發(fā)現(xiàn)功能來把下游服務(wù)器的配置動態(tài)化。這就導致 Ocelot 項目跟 Consul 的融合會比一般的服務(wù)復雜一點。
Install-Package Ocelot.Provider.Consul
首先我們在項目上使用 nuget 安裝 Ocelot.Provider.Consul 這個組件。
{"consul_server": "http://192.168.18.164:8500"
}
同樣我們需要在本地的 appsettings.json 文件內(nèi)指定 consul_server 的地址。再把 routes.json 文件的內(nèi)容全部遷移至 consul 的 key/value 上去,這個不在贅述。
?
注意,這里不是簡單的復制粘貼 routes.json 文件的內(nèi)容。
我們需要把原來的 DownstreamHostAndPorts 配置全部刪掉,替換成服務(wù)名,并且指定負載均衡的算法。
"ServierName" : "hotel_base",
"LoadBalanceOptions": {"Type": "LeastConnection"
}
在 "GlobalConfiguration" 節(jié)點指定 "ServiceDiscoveryProvider":
"ServiceDiscoveryProvider": {"Scheme": "http","Host": "192.168.18.164","Prot": 8500,"Type": "Consul"
}
ServiceDiscoveryProvider 節(jié)點指示了使用 Consul 做為服務(wù)發(fā)現(xiàn)的組件及Consul服務(wù)的基本信息。
public static void Main(string[] args){new WebHostBuilder().UseKestrel().UseContentRoot(Directory.GetCurrentDirectory()).ConfigureAppConfiguration((hostingContext, config) =>{var localconfig = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").AddEnvironmentVariables().Build();var consul_server = localconfig["consul_server"];config.AddConsul("gateway/routes.json", op => {op.ConsulConfigurationOptions = cco =>{cco.Address = new Uri(consul_server);};op.ReloadOnChange = true;});config.AddEnvironmentVariables();}).ConfigureServices(s => {s.AddOcelot().AddConsul().AddTransientDefinedAggregator<HotelDetailInfoForMobileAggregator>();}).ConfigureLogging((hostingContext, logging) =>{logging.AddConsole();}).UseIISIntegration().Configure(app =>{app.UseOcelot().Wait();}).Build().Run();}
我們改造一下 program 文件的 main 方法,在ConfigureAppConfiguration的配置方法內(nèi)首先獲取 consul_server 的地址。通過AddConsul方法指示獲取配置文件的地址。
以上跟服務(wù)的配置遷移都是一致的,除了以上操作使用 Consul 作為 ServiceDiscoveryProvider 還需要在 ConfigureServices 方法的配置函數(shù)內(nèi)指定 consul 相關(guān)的依賴注入。
s.AddOcelot().AddConsul()
我們運行起來所有的服務(wù)跟網(wǎng)關(guān)項目,訪問一下 /api/hotel 這個路由,可以看到請求被正確的轉(zhuǎn)發(fā)到了對應(yīng)的服務(wù)上了。
總結(jié)
以上我們演示了如何把服務(wù)的配置遷移到 Consul 的 Key/Value 對象上并且實現(xiàn)了配置的讀取及熱更新。演示了 Ocelot 網(wǎng)關(guān)的路由配置如何遷移到 Consul 的 Key/Value 對象上并且不再寫死下游服務(wù)的配置信息,而是使用 Consul 的服務(wù)發(fā)現(xiàn)能力動態(tài)獲取下游服務(wù)的配置信息。通過以上演示我們可以發(fā)現(xiàn)整個過程還是非常簡單易用的,雖然 Consul 做為配置中心功能相對于 apollo 等功能還不夠強大,比如沒有版本管理,用戶權(quán)限,審計等功能,但是對于一些小的微服務(wù)項目也已經(jīng)足夠了。如果你的微服務(wù)體系中使用了 Consul 做為服務(wù)注冊發(fā)現(xiàn)的組件,那么可以直接使用 Consul 來做為配置中心,這樣在能夠獲得基本的配置中心能力同時也省去了再部署一套單獨的配置中心的繁瑣操作。