Consul官網:https://www.consul.iohtml
Consul下載地址:https://www.consul.io/downloads.htmlweb
Consul nuget 命令:Install-Package Consuljson
個人理解是,Consul是一個服務管理者,系統中全部使用到的服務他都幫你管理好,促銷高峯須要新增服務的時候,服務開啓來就自動註冊到Consul中,服務下線關閉,也自動從Consul註銷,無縫銜接,對於使用者來講,你只須要跟Consul說我要某某某服務,Consul就會返回當前在Consul上註冊的可用的服務給回你,你也無需像之前那樣將服務的地址配置在系統當中,就好像DNS服務器那樣,你輸入域名,DNS服務器返回其中一個IP地址給你,而後你就能夠正常訪問, 另外在集羣環境下選擇服務的策略交給調用方,你能夠選擇隨機、輪詢、權重等方式,具體視乎你的需求。api
1、Windows系統啓動Consul服務器
這裏以Windows系統進行演示,實際項目中能夠搭建在Linux上,下載到本地以後解壓,使用命令行模式進入到Consul目錄,輸入命令啓動Consul服務:app
consul.exe agent -dev
啓動Consul成功,命令行信息中顯示,可使用地址: http://127.0.0.1:8500 打開UI管理界面進行查看管理操做。負載均衡
2、.NET Core+Consul 演示dom
一、新建一個ASP.NET Core Web 應用程序,nuget安裝Consul:Install-Package Consul 函數
二、增長用於Consul健康監測的Controller,這裏就是一個簡單的Controller、Action,能正常被訪問便可。微服務
namespace MsgService.Controllers { [Produces("application/json")] [Route("api/Health")] public class HealthController : Controller { [HttpGet] public IActionResult Get() { Console.WriteLine("健康檢查" + DateTime.Now); return Content("ok"); } } }
三、修改應用程序站點的Startup類 ,在函數Configure 中增長多一個參數 IApplicationLifetime appLifeTime,而後在Configure函數中增長註冊、註銷的代碼,這段代碼的意思是,當應用程序站點啓動或者註銷的時候,就會對Consul進行消息通知。這裏ConsulConfig方法裏寫死了我本機運行的Consul地址:http://127.0.0.1:8500,實際項目中確定是要作成配置的。
//Consul 新增 IApplicationLifetime appLifeTime參數 public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime appLifeTime) { //註冊Consul string ip = Configuration["ip"]; string port = Configuration["port"]; string serviceName = "MsgService"; string serviceId = serviceName + Guid.NewGuid(); using (var consulClient = new ConsulClient(ConsulConfig)) { AgentServiceRegistration asr = new AgentServiceRegistration { Address = ip, Port = Convert.ToInt32(port), ID = serviceId, Name = serviceName, Check = new AgentServiceCheck { DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), HTTP = $"http://{ip}:{port}/api/Health", Interval = TimeSpan.FromSeconds(10), Timeout = TimeSpan.FromSeconds(5), }, }; consulClient.Agent.ServiceRegister(asr).Wait(); } //註銷Consul appLifeTime.ApplicationStopped.Register(() => { using (var consulClient = new ConsulClient(ConsulConfig)) { Console.WriteLine("應用退出,開始從consul註銷"); consulClient.Agent.ServiceDeregister(serviceId).Wait(); } }); } //Consul 配置委託 private void ConsulConfig(ConsulClientConfiguration config) { config.Address = new Uri("http://127.0.0.1:8500"); //Demo硬編碼Consul的地址 config.Datacenter = "dc1"; }
四、修改應用程序站點的Program.BuildWebHost 方法,目的是方便咱們在web應用程序bin目錄下以指定的IP地址、指定的端口啓動服務
/// <summary> /// 設置NetCore監聽端口取命令行中的參數 /// </summary> /// <param name="args"></param> /// <returns></returns> public static IWebHost BuildWebHost(string[] args) { var config = new ConfigurationBuilder() .AddCommandLine(args) .Build(); string ip = config["ip"]; string port = config["port"]; Console.WriteLine($"ip={ip},port={port}"); return WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseUrls($"http://{ip}:{port}") .Build(); }
五、啓動服務
打開應用程序目錄定位在bin目錄下,使用命令行模式輸入命令,以指定的IP、指定的端口啓動服務, 一切正常的話,在consul管理界面能夠看到已經註冊上的服務信息。
這裏只註冊一個服務進行演示,在實際微服務項目中,確定是集羣環境的,好比同一個服務,你有4臺機器,那consul上就註冊了4個,服務名字都是同樣的,只是URL地址不同,當趕上促銷的時候,服務壓力比較大,這時候當要加多一臺服務器,新的服務就自動加到consul上來,消費者就從consul取其中一個服務進行調用。
dotnet 【應用程序.dll】 --ip 127.0.0.1 --port 6001
3、服務消費
一、新建一個.NET Core 控制檯應用程序;
二、nuget安裝Consul組件;
三、取出已經在Consul註冊的所有服務
static void Main(string[] args) { using (var consul = new Consul.ConsulClient(c => { c.Address = new Uri("http://127.0.0.1:8500"); })) { //取在Consul註冊的所有服務 var services = consul.Agent.Services().Result.Response; foreach (var s in services.Values) { Console.WriteLine($"ID={s.ID},Service={s.Service},Addr={s.Address},Port={s.Port}"); } } Console.ReadKey(); } }
如今在Consul已經註冊了3個MsgService服務,打印在控制檯上。
四、隨機從註冊的服務中取出其中一個服務
當咱們在consul上註冊了N個相同的服務以後,咱們確定不能每次都選取某一個服務的,否則得累死那臺服務,而其餘服務倒是空閒的狀態,所以咱們加入隨機選取的邏輯,從註冊的N個服務中,隨機選取其中一個服務,另外還有其餘好比輪詢,權重等等的策略,使得咱們更靈活的調用服務。
using (var consul = new Consul.ConsulClient(c => { c.Address = new Uri("http://127.0.0.1:8500"); //Consul地址 })) { //取出所有的MsgService服務 var services = consul.Agent.Services().Result.Response.Values.Where(p => p.Service.Equals("MsgService", StringComparison.OrdinalIgnoreCase)); //客戶端負載均衡,隨機選出一臺服務 Random rand = new Random(); var index = rand.Next(services.Count()); var s = services.ElementAt(index); Console.WriteLine($"Index={index},ID={s.ID},Service={s.Service},Addr={s.Address},Port={s.Port}"); }
五、服務調用
//向服務發送請求 using (var httpClient = new HttpClient()) using (var httpContent = new StringContent("{phoneNum:'119',msg:'help me'}", Encoding.UTF8, "application/json")) { var result = httpClient.PostAsync($"http://{s.Address}:{s.Port}/api/SMS/Send_LX", httpContent); Console.WriteLine($"調用{s.Service},狀態:{result.Result.StatusCode}"); }