.NET Core微服務一:Consul服務中心

 

.NET Core微服務一:Consul服務中心 http://www.javashuo.com/article/p-pnigqhxw-e.htmlhtml

.NET Core微服務二:Ocelot API網關 待更新web

.NET Core微服務三:polly熔斷與降級 待更新json

 


本文的項目代碼,在文章結尾處能夠下載。
api

本文使用的環境:Windows10 64位 + VS 2019 + .NET Core 3.1服務器

Consul有關介紹:https://www.jianshu.com/p/32dc52f28a14app

Consul官方網址:https://www.consul.io/負載均衡

 

 

1、安裝Consul異步

1.官網下載對應版本,並解壓出來async

 

2.打開cmd,cd到解壓的目錄,運行以下其中一條命令微服務

本次演示都在同一臺計算機上,因此本文選擇命令一;這兩條命令請在開發環境使用,生產環境不要使用。

命令一:「consul.exe agent -dev」服務中心的ip地址,將會使用127.0.0.1

命令二:「consul.exe agent -dev -client x.x.x.x」指定服務中心的ip地址

 

3.命令運行成功後,打開「http://127.0.0.1:8500/」,出現以下畫面

 

 

2、建立服務

1.服務端項目大致結構:

 

2.新建.NET Core類庫項目,命名爲「ClassLibrary」,而後NuGet搜索並安裝

「Consul」、「Microsoft.Extensions.Configuration」

Common.cs代碼:

 1 using Consul;  2 using Microsoft.Extensions.Configuration;=
 3 using System;  4 
 5 namespace ClassLibrary  6 {  7     public class Common  8  {  9         public static IConfiguration Configuration { get; } 10         static Common() 11  { 12             Configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", false, true).Build(); 13  } 14 
15         /// <summary>
16         /// 須要註冊的服務地址 17         /// </summary>
18         public static string ConsulServiceIP 19  { 20             get
21  { 22                 return Configuration["ConsulService:IP"]; 23  } 24  } 25 
26         /// <summary>
27         /// 須要註冊的服務端口 28         /// </summary>
29         public static int ConsulServicePort 30  { 31             get
32  { 33                 string str = Configuration["ConsulService:Port"]; 34                 return int.Parse(str); 35  } 36  } 37 
38         /// <summary>
39         /// 服務註冊 40         /// </summary>
41         public static void ConsulRegister() 42  { 43             ConsulClient client = new ConsulClient( 44                 (ConsulClientConfiguration c) =>
45  { 46                     c.Address = new Uri(Configuration["ConsulCenter:Address"]); //Consul服務中心地址
47                     c.Datacenter = Configuration["ConsulCenter:DataCenter"]; //指定數據中心,若是未提供,則默認爲代理的數據中心。
48  } 49  ); 50             string checkUrl = Configuration["ConsulCenter:CheckUrl"]; 51             client.Agent.ServiceRegister(new AgentServiceRegistration() 52  { 53                 ID = Guid.NewGuid().ToString(), //服務編號,不可重複
54                 Name = Configuration["ConsulService:Name"], //服務名稱
55                 Port = ConsulServicePort, //本程序的端口號
56                 Address = ConsulServiceIP, //本程序的IP地址
57                 Check = new AgentServiceCheck() 58  { 59                     DeregisterCriticalServiceAfter = TimeSpan.FromMilliseconds(1), //服務中止後多久註銷
60                     Interval = TimeSpan.FromSeconds(5), //服務健康檢查間隔
61                     Timeout = TimeSpan.FromSeconds(5), //檢查超時的時間
62                     HTTP = $"http://{ConsulServiceIP}:{ConsulServicePort}{checkUrl}" //檢查的地址
63  } 64  }); 65  } 66 
67  } 68 }

 

3.新建.NET Core的webapi項目,命名爲「ServiceStudent」,把「爲HTTPS配置」的勾選去掉

Controller代碼:

 1 using Microsoft.AspNetCore.Mvc;  2 using System;  3 using System.Collections.Generic;  4 
 5 namespace ServiceStudent.Controllers  6 {  7     [Route("api/[controller]/[action]")]  8  [ApiController]  9     public class DefaultController : ControllerBase 10  { 11         static List<Student> list = new List<Student>() { 12             new Student(){ ID = "001", StudentName = "學生1", StudentAge = 16 }, 13             new Student(){ ID = "002", StudentName = "學生2", StudentAge = 18 }, 14             new Student(){ ID = "003", StudentName = "學生3", StudentAge = 17 } 15  }; 16 
17         /// <summary>
18         /// 健康檢查接口 19         /// </summary>
20  [HttpGet] 21         public string Check() 22  { 23             return "1"; 24  } 25 
26  [HttpGet] 27         public List<Student> GetList() 28  { 29  Console.WriteLine(DateTime.Now.ToString()); 30             return list; 31  } 32 
33  [HttpGet] 34         public Student GetModel(string id) 35  { 36  Console.WriteLine(DateTime.Now.ToString()); 37             return list.Find(t => t.ID == id); 38  } 39  } 40 }

 

其中有一段健康檢查的接口,做用是讓服務中心知道服務沒有掛掉還能訪問,不須要什麼業務,因此怎麼簡單怎麼來:

 

Model代碼:

    public class Student { public string ID { get; set; } public string StudentName { get; set; } public int StudentAge { get; set; } }

 

appsettings.json加入:

  "ConsulCenter": {
    "Address": "http://127.0.0.1:8500",
    "CheckUrl": "/api/Default/Check",
    "DataCenter": "dc1"
  },
  "ConsulService": {
    "IP": "127.0.0.1",
    "Port": 33331,
    "Name": "Student"
  }

 

Program.cs的CreateHostBuilder方法改成:

public static IHostBuilder CreateHostBuilder(string[] args) { string ip = Common.ConsulServiceIP; int port = Common.ConsulServicePort; return Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>().UseUrls($"http://{ip}:{port}"); }); }

 

在Startup.cs的Configure方法中加入「ClassLibrary.Common.ConsulRegister();」

這樣一個「Student」服務就建立好了,「Teacher」服務也是如法炮製,可是須要改appsettings.json的服務名和端口號,代碼就不貼了,請到文章結尾處下載。

 

 

3、啓動服務

不能在VS中啓動,由於咱們已經在Program.cs自定義了IP和PORT。

打開cmd,cd到Debug目錄,各自運行「dotnet ServiceStudent.dll」和「dotnet ServiceTeacher.dll」。

請檢查端口有沒有被佔用或超出範圍,若是失敗了,在配置文件中換成端口試試。

 

服務運行成功後,打開「http://127.0.0.1:8500/」,以下畫面註冊成功

 

若是出現一項打X,那就是失敗,這個服務會在1分鐘以後被踢出列表

 

一個服務可能會部署到多個服務器上,用「Teacher」來模擬下多臺機器運行。

前面運行好的服務不要關閉,打開Teacher的Debug目錄下的配置文件,修改它的端口號,服務名不用改,再新開一個cmd,運行「dotnet ServiceTeacher.dll」

 

那麼服務中心就會有變化

 

 

4、使用服務

1.客戶端項目大致結構:

 

2.新建.net core類庫項目,命名爲「ClassLibrary」,而後NuGet搜索並安裝

「Consul」、「Microsoft.Extensions.Configuration」

Common.cs代碼:

using Consul; using Microsoft.Extensions.Configuration; using System; using System.Linq; using System.Net.Http; using System.Threading.Tasks; namespace ClassLibrary { public class Common { public static IConfiguration Configuration { get; } static Common() { Configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", false, true).Build(); } public static string ConsulAddress { get { return Configuration["ConsulAddress"]; } } /// <summary>
        /// 獲取服務 /// </summary>
        public static string GetService(string serviceName) { ConsulClient client = new ConsulClient(c => c.Address = new Uri(ConsulAddress)); var response = client.Agent.Services().Result.Response; //服務名稱區分大小寫,若要不區分:Equals(serviceName, StringComparison.OrdinalIgnoreCase)
            var services = response.Where(s => s.Value.Service.Equals(serviceName)).Select(s => s.Value); //進行取模,隨機取得一個服務器,或者使用其它負載均衡策略
            var service = services.ElementAt(Environment.TickCount % services.Count()); return service.Address + ":" + service.Port; } /// <summary>
        /// 獲取服務(異步方法) /// </summary>
        public async Task<string> GetService2(string serviceName) { ConsulClient client = new ConsulClient(c => c.Address = new Uri(ConsulAddress)); var response = (await client.Agent.Services()).Response; //服務名稱區分大小寫,若要不區分:Equals(serviceName, StringComparison.OrdinalIgnoreCase)
            var services = response.Where(s => s.Value.Service.Equals(serviceName)).Select(s => s.Value); //進行取模,隨機取得一個服務器,或者使用其它負載均衡策略
            var service = services.ElementAt(Environment.TickCount % services.Count()); return service.Address + ":" + service.Port; } public static string HttpGetString(string url) { HttpClient httpClient = new HttpClient(); string result = httpClient.GetAsync(url) .Result.Content.ReadAsStringAsync().Result; httpClient.Dispose(); return result; } public static T HttpGetObject<T>(string url) { string result = HttpGetString(url); return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(result); } } }

 

3.新建.NET Core的webapi項目,命名爲「ClientSite」,把「爲HTTPS配置」的勾選去掉

StudentController代碼:

 1 using ClassLibrary;  2 using Microsoft.AspNetCore.Mvc;  3 using System.Collections.Generic;  4 
 5 namespace ClientSite.Controllers  6 {  7     [Route("api/[controller]/[action]")]  8  [ApiController]  9     public class StudentController : ControllerBase 10  { 11  [HttpGet] 12         public object GetList() 13  { 14             string ip = Common.GetService("Student"); 15             List<Student> list = Common.HttpGetObject<List<Student>>($"http://{ip}/api/Default/GetList"); 16             return new
17  { 18                 address = ip, 19                 data = list 20  }; 21  } 22 
23  [HttpGet] 24         public object GetModel(string id) 25  { 26             string ip = Common.GetService("Student"); 27             Student model = Common.HttpGetObject<Student>($"http://{ip}/api/Default/GetModel?id=" + id); 28             return new
29  { 30                 address = ip, 31                 data = model 32  }; 33  } 34  } 35 }

 

TeacherController代碼:

 1 using ClassLibrary;  2 using Microsoft.AspNetCore.Mvc;  3 using System.Collections.Generic;  4 
 5 namespace ClientSite.Controllers  6 {  7     [Route("api/[controller]/[action]")]  8  [ApiController]  9     public class TeacherController : ControllerBase 10  { 11  [HttpGet] 12         public object GetList() 13  { 14             string ip = Common.GetService("Teacher"); 15             List<Teacher> list = Common.HttpGetObject<List<Teacher>>($"http://{ip}/api/Default/GetList"); 16             return new
17  { 18                 address = ip, 19                 data = list 20  }; 21  } 22 
23  [HttpGet] 24         public object GetModel(string id) 25  { 26             string ip = Common.GetService("Teacher"); 27             Teacher model = Common.HttpGetObject<Teacher>($"http://{ip}/api/Default/GetModel?id=" + id); 28             return new
29  { 30                 address = ip, 31                 data = model 32  }; 33  } 34  } 35 }

 

appsettings.json加入:

"ConsulAddress": "http://127.0.0.1:8500"

 

4.用VS啓動站點,而後用postman訪問

「http://localhost:3336/api/Student/GetList」

「http://localhost:3336/api/Student/GetModel?id=003」

 

屢次訪問「http://localhost:3336/api/Teacher/GetList」,則address會隨機切換,注意看返回的端口號

 

 

 

代碼:https://files.cnblogs.com/files/shousiji/netcore_wfw.rar

相關文章
相關標籤/搜索