庐山真面目之四微服务架构Consul和Ocelot简单版本实现

一、简介

       在上一篇文章《庐山真面目之三微服务架构Consul简单版本实现》中,我们已经探讨了如何搭建基于Consul组件的微服务架构,可能很多人感觉很简单。没错,的确很简单,因为我的每篇文章只会解决一个问题,这样更单纯、更精准。如果我们把所有的东西都放在一篇文章里,太多了,不利于学习和查看。我们通过上一篇文章可知,在客户端访问 Consul 组件管理的业务服务实例是多么的麻烦,需要自己写代码实现。项目少,无所谓,只要项目一大,或者项目多了,规模大了,都会对管理和维护带来很大的挑战,毕竟,人喜欢操作简单的东西,想抬杠的免开尊口,主要是没必要。今天我们就解决客户端手写调用策略的问题。



  1、说明

        我先说明一下,这个实现的版本只过是测试版本,以后会把相关的技术点都增加上去,我们一步一步的演化而来,如果是大牛,就可以直接跳过,因为这些东西相对于您来说,这个太简单了。特别说明,这里的所有代码都经过测试,所以大家可以放心使用。



  2、开发环境

        
以下就是开发环境,不用多说,都很简单,一看就知道。

       (1)、开发工具:Visual
Studio 2019

       (2)、开发语言:C#

       (3)、开发平台:Net
Core3.1,跨平台。

       (4)、服务注册:Consul,服务注册、发现中心

       (5)、网关服务:Ocelot 开源组件,负载均衡,服务治理。

       (6)、操作系统:Windows
10,64bit。



  3、我们的目标

        今天我们要解决的问题是如何做到服务实例调用策略不许要手写,并且还能实现负载均衡,其他问题,比如:Consul 本身的集群的问题暂时就不考虑,我们会一步一步的演变下去。

                  

二、Consul注册、发现服务组件的简介。
                    

         在这里我们只是做简单的介绍,不会详细讨论它的所有技术点,没有那么大的篇幅,再说这样做也就跑题了。如果大家想去学习Consul的有关内容,地址我已经贴出来了,大家可以自行恶补。

         Consul是一个服务网格(微服务间的 TCP/IP,负责服务之间的网络调用、限流、熔断和监控)解决方案,它是一个一个分布式的,高度可用的系统,而且开发使用都很简便。它提供了一个功能齐全的控制平面,主要特点是:服务发现、健康检查、键值存储、安全服务通信、多数据中心。

        上面的一幅图就说明了Consul的工作原理。S-A是使用服务的客户端,他不用关系有多少个服务,只要它需要的时候,他就会向Consul服务中心发出请求,Consul中心就会把和服务名称(在Consul中的名称,也可以说是服务的类别名称)匹配的、在此注册的所有服务实例的地址信息全部返回给S-A客户端,然后客户端,可以根据自己的情况,决定调用的具体策略,可以轮训、可以权重、可以随机,当然其他方式也可以,但是这些工作必须由使用服务的客户端S-A自行解决。

         S-B-1、S-B-2、S-B-3等是在Consul中心注册的服务实例,包括服务实例的地址、端口号、ID名称、服务类别名称等信息。这些服务实例,每个服务实例都有自己的ID名称,多个服务实例可以取一个相同的名称,其实,这个名称是用于分类的。Consul中心查找的时候就是通过这个名称来查找的。这些服务实例,在应用程序一开始的时候就开始注册,并且只注册一次。

         所有的服务实例都注册成功了,时间一分一秒的过去,一个小时之后或者一段时候之后服务还存在吗?我们如何判断呢?这就涉及到我们要谈的第三个方面,健康监测,英文叫:Health Check。Consul中心为我们提供了现成的接口,可以定义针对服务的健康检查,这个健康检查是一个完整的策略,包括:如果检查失败,多久注销服务;服务检查的时间间隔;还有调用检查的超时时间等。这样就能为我们提供一个比较完备的服务注册、发现和检测的解决方案。

        总结如下:

            1
、服务自动注册,可以发现新服务。

            2
、健康检测,可以过滤掉线服务。

            3
、客户端要完成服务调用逻辑,比较麻烦,没有Nginx
方便。



    Consul文档:https://www.consul.io/docs

    Consul官网:https://www.consul.io

三、Ocelot服务组件简介。

              

       今天要给大家介绍的Ocelot是一个基于 .net
core的开源WebAPI服务网关项目,它的功能非常强大,包括了路由、请求聚合、服务发现、认证鉴权、限流、负载均衡等功能。而这些功能都可以直接通过修改json配置文件即可使用,非常方便。Ocelot是系统中对外暴露的一个请求入口,所有外部接口都必须通过这个网关才能向下游API发出请求,就如地铁中的安检系统,所有人都必须经过安检才能乘坐地铁。

       当然了,我今天肯定也不会对Ocelot服务组件进行详细的讨论,它有官网和详细的文档,如果想看它的源码也是没有问题的,因为它是开源的。如果大家想去学习的话,可以直接点击我贴出的连接。

  官网:https://threemammals.com/ocelot

    文档:https://ocelot.readthedocs.io/en/latest

    Git:https://github.com/ThreeMammals/Ocelot



四、微服务架构Consul和Ocelot版本实现


      上一篇文章我们解决了业务服务实例的发现和注册问题,当然也有健康检查,可以做到服务实例的动态伸缩。非常给力,也非常兴奋,因为我们又战胜了一个问题,做技术的人员都懂我说的意思。兵来将挡水来土掩,今天我们要解决手写代码去实现服务实例的调用策略。废话少说,我们开始吧。



      1、下载 Consul 服务组件。

              官网下载:https://www.consul.io/downloads

                         

              Consul下载成功后,放在没有包含中文的目录里面,这是我的个人的习惯。

              我的运行目录:D:\Programs\MicroServices\Consul_1.8.4_windows_amd64

      

      2、配置 Consul 服务组件。

              切换到当前目录,执行如下命令:Consul
agent –dev

    

              我们也可以通过浏览器查看 Consul服务中心是否启动成功,地址:http://localhost:8500,如果成功,效果如下:

    



      3、建立项目,并为项目引入 Consul包。

              (1)、PatrickLiu.MicroService.Client(ASPNETCORE
MVC),客户端项目。

      
            代码如下:
             【1】、HomeController.cs的代码

                 

 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Net.Http;
5 using Consul;
6 using Microsoft.AspNetCore.Mvc;
7 using Microsoft.Extensions.Logging;
8 using PatrickLiu.MicroService.Interfaces;
9 using PatrickLiu.MicroService.Models;
10
11 namespace PatrickLiu.MicroService.Client.Controllers
12 {
13 public class HomeController : Controller
14 {
15 private readonly ILogger<HomeController> _logger;
16 private readonly IUserService _userService;
17
18 /// <summary>
19 /// 初始化该类型的新实例。
20 /// </summary>
21 /// <param name="logger">注入日志对象。</param>
22 /// <param name="userService">注入用户服务对象。</param>
23 public HomeController(ILogger<HomeController> logger, IUserService userService)
24 {
25 _logger = logger;
26 _userService = userService;
27 }
28
29 /// <summary>
30 /// 首页。
31 /// </summary>
32 /// <returns></returns>
33 public IActionResult Index()
34 {
35 #region 通过 Ocelot 网关访问服务实例。
36
37 string url = "http://localhost:6299/gate/users/all";//这个地址是网关的
38
39 #endregion
40
41 string content = InvokeAPI(url);
42 this.ViewBag.Users = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<User>>(content);
43 Console.WriteLine($"This is {url} Invoke.");
44
45 #endregion
46
47 return View();
48 }
49
50
51 /// <summary>
52 /// 封装 HttpClient 实例,提供 Http 调用。
53 /// </summary>
54 /// <param name="url">http url 的地址。</param>
55 /// <returns>返回结束数据,格式:JSON。</returns>
56 public static string InvokeAPI(string url)
57 {
58 using (HttpClient client = new HttpClient())
59 {
60 HttpRequestMessage message = new HttpRequestMessage();
61 message.Method = HttpMethod.Get;
62 message.RequestUri = new Uri(url);
63 var result = client.SendAsync(message).Result;
64 string conent = result.Content.ReadAsStringAsync().Result;
65 return conent;
66 }
67 }
68 }
69 }

             【2】、修改Startup.cs代码,红色增加的代码。
                

1 public void ConfigureServices(IServiceCollection services)
2 {
3 services.AddControllersWithViews();
4
5 services.AddSingleton<IUserService, UserService>();
6 }

    (2)、PatrickLiu.MicroService.Interfaces(NETCORE 类库),定义接口。

      

           代码如下:

                        

 1 using PatrickLiu.MicroService.Models;
2 using System.Collections.Generic;
3
4 namespace PatrickLiu.MicroService.Interfaces
5 {
6 /// <summary>
7 /// 用户服务的接口定义。
8 /// </summary>
9 public interface IUserService
10 {
11 /// <summary>
12 /// 查找指定主键的用户实例对象。
13 /// </summary>
14 /// <param name="id">用户的主键。</param>
15 /// <returns>返回查找到的用户实例对象。</returns>
16 User FindUser(int id);
17
18 /// <summary>
19 /// 获取所有用户的实例集合。
20 /// </summary>
21 /// <returns>返回所有的用户实例。</returns>
22 IEnumerable<User> UserAll();
23 }
24 }

    (3)、PatrickLiu.MicroService.Models(NETCORE 类库),定义实例类型。

      

                       代码如下:
            

 1 using System;
2
3 namespace PatrickLiu.MicroService.Models
4 {
5 /// <summary>
6 /// 用户模型。
7 /// </summary>
8 public class User
9 {
10 /// <summary>
11 /// 获取或者设置用户主键。
12 /// </summary>
13 public int ID { get; set; }
14
15 /// <summary>
16 /// 获取或者设置用户姓名。
17 /// </summary>
18 public string Name { get; set; }
19
20 /// <summary>
21 /// 获取或者设置用户账号名称。
22 /// </summary>
23 public string Account { get; set; }
24
25 /// <summary>
26 /// 获取或者设置用户密码。
27 /// </summary>
28 public string Password { get; set; }
29
30 /// <summary>
31 /// 获取或者设置用户的电子邮箱地址。
32 /// </summary>
33 public string Email { get; set; }
34
35 /// <summary>
36 /// 获取或者设置用户角色。
37 /// </summary>
38 public string Role { get; set; }
39
40 /// <summary>
41 /// 获取或者设置用户的登录时间。
42 /// </summary>
43 public DateTime LoginTime { get; set; }
44 }
45 }

    (4)、PatrickLiu.MicroService.Services(NETCORE 类库),定义服务实现。

      

                       代码如下:
            

 1 using PatrickLiu.MicroService.Interfaces;
2 using PatrickLiu.MicroService.Models;
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6
7 namespace PatrickLiu.MicroService.Services
8 {
9 /// <summary>
10 /// 实现用户服务接口的实现类型。
11 /// </summary>
12 public class UserService : IUserService
13 {
14 private IList<User> dataList;
15
16 /// <summary>
17 /// 初始化类型的实例
18 /// </summary>
19 public UserService()
20 {
21 dataList = new List<User>()
22 { new User {ID=1,Name="黄飞鸿",Account="HuangFeiHong",Password="HuangFeiHong123456",Email="huangFeiHong@sina.com", Role="Admin", LoginTime=DateTime.Now },
23 new User {ID=2,Name="洪熙官",Account="HongXiGuan",Password="HongXiGuan54667",Email="HongXiGuan@sina.com", Role="Admin", LoginTime=DateTime.Now.AddDays(-5) },
24 new User {ID=3,Name="方世玉",Account="FangShiYu",Password="FangShiYu112233",Email="fangShiYu@163.com", Role="Admin", LoginTime=DateTime.Now.AddDays(-30) },
25 new User {ID=4,Name="苗翠花",Account="MiaoCuiHua",Password="MiaoCuiHua887766",Email="miaoCuiHua@sohu.com", Role="Admin", LoginTime=DateTime.Now.AddDays(-90) },
26 new User {ID=5,Name="严咏春",Account="YanYongChun",Password="YanYongChun09392",Email="yanYongChun@263.com", Role="Admin", LoginTime=DateTime.Now.AddMinutes(-50) }};
27 }
28
29 /// <summary>
30 /// 查找指定主键的用户实例对象。
31 /// </summary>
32 /// <param name="id">用户的主键。</param>
33 /// <returns>返回查找到的用户实例对象。</returns>
34 public User FindUser(int id)
35 {
36 return dataList.FirstOrDefault(user => user.ID == id);
37 }
38
39 /// <summary>
40 /// 获取所有用户的实例集合。
41 /// </summary>
42 /// <returns>返回所有的用户实例。</returns>
43 public IEnumerable<User> UserAll()
44 {
45 return dataList;
46 }
47 }
48 }

    (5)、PatrickLiu.MicroService.ServiceInstance(ASPNETCORE
WEBAPI),接口服务。
            
           【1】、安装Consul服务组件,以支持Consul服务。
               
命令:Install-Package Consul
                可以在项目菜单【依赖项】菜单上点击右键,选择【管理 NuGet 程序包】来安装Consul服务。

                        【2】、HealthController.cs,主要用于Consul服务的健康检查。

                               

 1 using System;
2 using Microsoft.AspNetCore.Mvc;
3 using Microsoft.Extensions.Configuration;
4
5 namespace PatrickLiu.MicroService.ServiceInstance.Controllers
6 {
7 /// <summary>
8 /// 健康检查的控制器。
9 /// </summary>
10 [ApiController]
11 [Route("api/[controller]")]
12 public class HealthController : ControllerBase
13 {
14 private IConfiguration _configuration;
15
16 /// <summary>
17 /// 初始化该类型的新实例。
18 /// </summary>
19 /// <param name="configuration">配置接口。</param>
20 public HealthController(IConfiguration configuration)
21 {
22 _configuration = configuration;
23 }
24
25 /// <summary>
26 /// 要调用的接口。
27 /// </summary>
28 [HttpGet]
29 [Route("Index")]
30 public IActionResult Index()
31 {
32 Console.WriteLine($"This is HealhController {_configuration["port"]} Invoke");
33 return Ok();
34 }
35 }
36 }

       【3】、UsersController.cs,主要是业务类型,内容很简单。
                

  1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Threading;
5 using Microsoft.AspNetCore.Authorization;
6 using Microsoft.AspNetCore.Mvc;
7 using Microsoft.Extensions.Configuration;
8 using Microsoft.Extensions.Logging;
9 using PatrickLiu.MicroService.Interfaces;
10 using PatrickLiu.MicroService.Models;
11
12 namespace PatrickLiu.MicroService.ServiceInstance.Controllers
13 {
14 /// <summary>
15 /// 用户的 API 类型。
16 /// </summary>
17 [Route("api/[controller]")]
18 [ApiController]
19 public class UsersController : ControllerBase
20 {
21 #region 私有字段
22
23 private readonly ILogger<UsersController> _logger;
24 private readonly IUserService _userService;
25 private IConfiguration _configuration;
26
27 #endregion
28
29 #region 构造函数
30
31 /// <summary>
32 /// 初始化该类型的新实例。
33 /// </summary>
34 /// <param name="logger">日志记录器。</param>
35 /// <param name="userService">用户服务接口。</param>
36 /// <param name="configuration">配置服务。</param>
37 public UsersController(ILogger<UsersController> logger, IUserService userService, IConfiguration configuration)
38 {
39 _logger = logger;
40 _userService = userService;
41 _configuration = configuration;
42 }
43
44 #endregion
45
46 #region 实例方法
47
48 /// <summary>
49 /// 获取一条记录
50 /// </summary>
51 /// <param name="id"></param>
52 /// <returns></returns>
53 [HttpGet]
54 [Route("Get")]
55 public User Get(int id)
56 {
57 return _userService.FindUser(id);
58 }
59
60 /// <summary>
61 /// 获取所有记录。
62 /// </summary>
63 /// <returns></returns>
64 [HttpGet]
65 [Route("All")]
66 //[Authorize]
67 public IEnumerable<User> Get()
68 {
69 Console.WriteLine($"This is UsersController {this._configuration["port"]} Invoke");
70
71 return this._userService.UserAll().Select((user => new User
72 {
73 ID = user.ID,
74 Name = user.Name,
75 Account = user.Account,
76 Password = user.Password,
77 Email = user.Email,
78 Role = $"{this._configuration["ip"]}:{this._configuration["port"]}",
79 LoginTime = user.LoginTime
80 })); ;
81 }
82
83 /// <summary>
84 /// 超时处理
85 /// </summary>
86 /// <returns></returns>
87 [HttpGet]
88 [Route("Timeout")]
89 public IEnumerable<User> Timeout()
90 {
91 Console.WriteLine($"This is Timeout Start");
92 //超时设置。
93 Thread.Sleep(3000);
94
95 Console.WriteLine($"This is Timeout End");
96
97 return this._userService.UserAll().Select((user => new User
98 {
99 ID = user.ID,
100 Name = user.Name,
101 Account = user.Account,
102 Password = user.Password,
103 Email = user.Email,
104 Role = $"{this._configuration["ip"]}:{this._configuration["port"]}",
105 LoginTime = user.LoginTime
106 })); ;
107 }
108
109 #endregion
110 }
111 }

            【4】、增加扩展类型:ConsulExtension.cs
                

 1 using Consul;
2 using Microsoft.Extensions.Configuration;
3 using Microsoft.Extensions.Hosting;
4 using System;
5
6 namespace PatrickLiu.MicroService.ServiceInstance.Utilities
7 {
8 /// <summary>
9 /// Consul 静态扩展类。
10 /// </summary>
11 public static class ConsulExtension
12 {
13 /// <summary>
14 ///类型初始化器,初始化 Consul 网址和数据中心。
15 /// </summary>
16 static ConsulExtension()
17 {
18 Uri = new Uri("http://localhost:8500");
19 DataCenter = "dc1";
20 }
21
22 /// <summary>
23 /// 获取或者设置 Consul 的网址。
24 /// </summary>
25 public static Uri Uri { get; set; }
26
27 /// <summary>
28 /// 获取或者设置数据中心。
29 /// </summary>
30 public static string DataCenter { get; set; }
31
32 /// <summary>
33 /// 向 Consul 服务中心注册服务实例。
34 /// </summary>
35 /// <param name="configuration">配置对象。</param>
36 /// <param name="consulServiceName">在 Consul 服务中心注册的服务类别名称,多个实例的 ID 可以属于一个服务类别名称。</param>
37 /// <param name="serviceID">服务实例的主键值,必须唯一。</param>
38 public static void ConsulRegist(this IConfiguration configuration,string consulServiceName, string serviceID)
39 {
40 if (string.IsNullOrEmpty(consulServiceName) || string.IsNullOrWhiteSpace(consulServiceName))
41 {
42 throw new ArgumentNullException("consulServiceName is null");
43 }
44 if (string.IsNullOrEmpty(serviceID) || string.IsNullOrWhiteSpace(serviceID))
45 {
46 throw new ArgumentNullException("serviceID is null.");
47 }
48
49 using (ConsulClient client = new ConsulClient(config =>
50 {
51 config.Address = Uri;
52 config.Datacenter = DataCenter;
53 }))
54 {
55 string ip = configuration["ip"];
56 int port = int.Parse(configuration["port"]);
57 int weight = string.IsNullOrWhiteSpace(configuration["weight"]) ? 1 : int.Parse(configuration["weight"]);
58
59 client.Agent.ServiceRegister(new AgentServiceRegistration()
60 {
61 ID = serviceID,
62 Name = consulServiceName,
63 Address = ip,
64 Port = port,
65 Tags = new string[] { weight.ToString() },
66 Check = new AgentServiceCheck()
67 {
68 Interval = TimeSpan.FromSeconds(12),
69 HTTP = $"http://{ip}:{port}/API/Health/Index",
70 Timeout = TimeSpan.FromSeconds(5),
71 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(20)
72 }
73 }).Wait();
74 Console.WriteLine($"注册服务:{ip}:{port}--Weight:{weight}");
75 };
76 }
77
78 /// <summary>
79 /// 向 Consul 服务中心注销服务实例。
80 /// </summary>
81 /// <param name="applicationLifetime">配置对象。</param>
82 /// <param name="serviceID">服务实例的主键值,必须唯一。</param>
83 public static void ConsulDown(this IHostApplicationLifetime applicationLifetime, string serviceID)
84 {
85 if (string.IsNullOrEmpty(serviceID) || string.IsNullOrWhiteSpace(serviceID))
86 {
87 throw new ArgumentNullException("serviceID is null");
88 }
89 applicationLifetime.ApplicationStopped.Register(() =>
90 {
91 using (var consulClient = new ConsulClient(config => { config.Address = Uri; config.Datacenter = DataCenter; }))
92 {
93 Console.WriteLine("服务已经退出");
94 consulClient.Agent.ServiceDeregister(serviceID);
95 }
96 });
97 }
98 }
99 }


            【5】、修改 Startup.cs 代码。

          

 1 using Consul;
2 using Microsoft.AspNetCore.Builder;
3 using Microsoft.AspNetCore.Hosting;
4 using Microsoft.Extensions.Configuration;
5 using Microsoft.Extensions.DependencyInjection;
6 using Microsoft.Extensions.Hosting;
7 using PatrickLiu.MicroService.Interfaces;
8 using PatrickLiu.MicroService.ServiceInstance.Utilities;
9 using PatrickLiu.MicroService.Services;
10 using System;
11 using System.Security.Policy;
12
13 namespace PatrickLiu.MicroService.ServiceInstance
14 {
15 /// <summary>
16 /// 应用程序启动配置
17 /// </summary>
18 public class Startup
19 {
20 /// <summary>
21 /// 构造函数注入配置对象
22 /// </summary>
23 /// <param name="configuration">配置实例</param>
24 public Startup(IConfiguration configuration)
25 {
26 Configuration = configuration;
27 }
28
29 /// <summary>
30 /// 获取配置实例。
31 /// </summary>
32 public IConfiguration Configuration { get; }
33
34 /// <summary>
35 /// 配置注入对象。
36 /// </summary>
37 /// <param name="services"></param>
38 public void ConfigureServices(IServiceCollection services)
39 {
40 //其他代码省略
41 services.AddSingleton<IUserService, UserService>();
42 }
43
44 /// <summary>
45 /// 配置 HTTP 处理管道。
46 /// </summary>
47 /// <param name="app">应用程序对象。</param>
48 /// <param name="env">环境对象。</param>
49 /// <param name="applicationLifetime">应用程序生命周期的对象。</param>
50 public void Configure(IApplicationBuilder app, IWebHostEnvironment env,IHostApplicationLifetime applicationLifetime)
51 {
52 //其他代码省略
53 #region Consul 注册
54
55 string serviceID = $"Service:{Configuration["ip"]}:{Configuration["port"]}---{Guid.NewGuid()}";
56 string consuleServiceName = "PatrickLiuService";
57
58 //注册服务。
59 Configuration.ConsulRegist(consuleServiceName,serviceID);
60
61 //注销服务
62 applicationLifetime.ConsulDown(serviceID);
63
64 #endregion
65 }
66 }
67 }

            【6】、修改 Program.cs 代码,红色标注代表增加的代码。

            

 1 using System.IO;
2 using Microsoft.AspNetCore.Hosting;
3 using Microsoft.Extensions.Configuration;
4 using Microsoft.Extensions.Hosting;
5
6 namespace PatrickLiu.MicroService.ServiceInstance
7 {
8 public class Program
9 {
10 public static void Main(string[] args)
11 {
12 new ConfigurationBuilder()
13 .SetBasePath(Directory.GetCurrentDirectory())
14 .AddCommandLine(args)//支持命令行
15 .Build();
16
17 CreateHostBuilder(args).Build().Run();
18 }
19
20 public static IHostBuilder CreateHostBuilder(string[] args) =>
21 Host.CreateDefaultBuilder(args)
22 .ConfigureWebHostDefaults(webBuilder =>
23 {
24 webBuilder.UseStartup<Startup>();
25 });
26 }
27 }

    (6)、PatrickLiu.MicroService.Gateway(ASPNETCORE
WEBAPI),网关服务。

      

                      【1】、安装Ocelot组件包。

                              在【程序包管理器控制台】执行命令

                              命令:Install-Package
Ocelot

        

                              当然也可以在项目下的【依赖项】上点右键,点击【管理NuGet程序包】菜单,在【浏览】项先安装,输入Ocelot,在右侧安装则可以。



                      【2】、安装Ocelot.Provider.Consul组件包。

                               在【程序包管理器控制台】执行命令。

                               命令:Intall-Package
Ocelot.Provider.Consul

        

                               当然也可以在项目下的【依赖项】上点右键,点击【管理NuGet程序包】菜单,在【浏览】项先安装,输入Ocelot.Provider.Consul,在右侧安装则可以。



                      【3】、配置Startup.cs文件。

        

                      【4】、增加JSON配置文件,文件名:configuration.json。

          

                      【5】、修改
Program.cs 文件,使用上面增加的JSON配置文件。

          

                      【6】、启动网关实例。

                              命令:dotnet PatrickLiu.MicroService.Gateway.dll
–urls=http://*:6299 –port=6299

       

                      【7】、验证是否启动成功。

                              网关地址:http://localhost:6299/gate/users/all,能获取到数据表示一切成功。

                              截图如下:

                                  



      4、编译项目,发布4个服务实例,独立进程承载。

               再次提醒大家,在开始启动这4个服务实例之前,必须启动Consul服务中心。


              (1)、dotnet
PatrickLiu.MicroService.ServiceInstance.dll --urls="http://*:5726"
--ip="127.0.0.1" --port=5726

          

健康检查如图:

    

              (2)、dotnet
PatrickLiu.MicroService.ServiceInstance.dll --urls="http://*:5727"
--ip="127.0.0.1" --port=5727

          

健康检查如图:

    

              (3)、dotnet
PatrickLiu.MicroService.ServiceInstance.dll --urls="http://*:5728"
--ip="127.0.0.1" --port=5728

          
 

健康检查如图:

          

              (4)、dotnet
PatrickLiu.MicroService.ServiceInstance.dll --urls="http://*:5729"
--ip="127.0.0.1" --port=5729

          

健康检查如图:
          

以上是我们成功启动了4个服务实例,并且在Consul
服务中心注册成功,也可以执行健康检查,功能基本完善了。让我们看看4个服务实例在Consul中心的样子吧。

        

            注册的服务详情。

           



      5、客户端通过网关访问 Consul服务,最终访问我们服务实例。

         

              客户端我们自己实现的轮训策略,每次刷新,端口号都变,效果如图:

                  5726端口的数据:

    

                  5727端口的数据:

    

                  5728端口的数据:

    

                  5729端口的数据:

    

        6、我们的结论。

              我们解决了服务的发现和注册问题,也解决了客户端访问的问题,很不错,我们还需继续努力。实话实说,这样的架构肯定还不能在产品环境里面使用,因为有太多的问题了。当下就有一个可靠性的问题,如果这个单节点的Consul服务挂掉,怎么办?整个系统就会垮掉,我们为了增加系统的高可用性,需要对Consul组件进行升级,它需要集群来提供高可用。这就是我们下一篇文章要解决的问题,很有挑战啊。

五、
结束语

 
      好了,今天就写到这里了。完整高楼平地起,我们通过不断的努力,不断的解决遇到的问题,我们的知识也在剧增,眼界也就更宽广了。俗话说得好,兵来将挡水来土掩,努力吧,每天进步一点点。

庐山真面目之四微服务架构Consul和Ocelot简单版本实现的更多相关文章

  1. 庐山真面目之四微服务架构Consul集群和Nginx版本实现

    庐山真面目之四微服务架构Consul集群和Nginx版本实现 一.简介      在上一篇文章<庐山真面目之三微服务架构Consul版本实现>中,我们已经探讨了如何搭建基于单节点Consu ...

  2. 庐山真面目之六微服务架构Consul集群、Ocelot网关集群和Nginx版本实现

    庐山真面目之六微服务架构Consul集群.Ocelot网关集群和Nginx版本实现 一.简介      在上一篇文章<庐山真面目之五微服务架构Consul集群.Ocelot网关和Nginx版本实 ...

  3. 庐山真面目之七微服务架构Consul集群、Ocelot网关集群和IdentityServer4版本实现

    庐山真面目之七微服务架构Consul集群.Ocelot网关集群和IdentityServer4版本实现 一.简介      在上一篇文章<庐山真面目之六微服务架构Consul集群.Ocelot网 ...

  4. 庐山真面目之三微服务架构Consul版本实现

    庐山真面目之三微服务架构Consul版本实现 一.简介           在上一篇文章<庐山真面目之二微服务架构NGINX版本实现>中,我们已经探讨了如何搭建基于Nginx 网关的微服务 ...

  5. 庐山真面目之十四微服务架构的Docker虚拟技术深入探究

    庐山真面目之十四微服务架构的Docker虚拟技术深入探究 一.我的开场白 曾几何时,分布式的发展也影响了后来的微服务架构的实现方式.到了现在,只要涉及到互联网技术领域,就会设计一个概念,那就是微服务. ...

  6. 庐山真面目之八微服务架构 NetCore 基于 Dockerfile 文件部署

    庐山真面目之八微服务架构 NetCore 基于 Dockerfile 文件部署 一.简介      从今天开始,不出意外的话,以后所写的文章中所介绍项目的部署环境都应该会迁移到Linux环境上,而且是 ...

  7. 基于.net core微服务(Consul、Ocelot、Docker、App.Metrics+InfluxDB+Grafana、Exceptionless、数据一致性、Jenkins)

    1.微服务简介 一种架构模式,提倡将单一应用程序划分成一组小的服务,服务之间互相协调.互相配合,为用户提供最终价值.每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(RESTfu ...

  8. 庐山真面目之十二微服务架构基于Docker搭建Consul集群、Ocelot网关集群和IdentityServer版本实现

    庐山真面目之十二微服务架构基于Docker搭建Consul集群.Ocelot网关集群和IdentityServer版本实现 一.简介      在第七篇文章<庐山真面目之七微服务架构Consul ...

  9. 庐山真面目之九微服务架构 NetCore 基于 Docker 基础镜像和挂载文件部署

    庐山真面目之九微服务架构 NetCore 基于 Docker 基础镜像和挂载文件部署 一.简介      我们在上一篇文章<庐山真面目之八微服务架构 NetCore 基于 Dockerfile ...

随机推荐

  1. 在java的多态调用中,new的是哪一个类就是调用的哪个类的方法。

    在java的多态调用中,new的是哪一个类就是调用的哪个类的方法.(x) 原因: ava多态有两种情况:重载和覆写 在覆写中,运用的是动态单分配,是根据new的类型确定对象,从而确定调用的方法: 在重 ...

  2. request-promise post请求微信小程序云函数调用http

    微信小程序不支持http调用,但是可以通过服务器或者云函数实现,云函数相当于云服务器中的一段代码,可以使用http协议 首先要云函数安装request-promise,右键云函数,在终端中打开,输入n ...

  3. android自带下拉刷新SwipeRefreshLayout

    也是一个布局容器,只有一个子组件,类似scrollView <?xml version="1.0" encoding="utf-8"?> <a ...

  4. 【垃圾回收-CMS】Java内存回收实践经验 防止内存报警

    jdk6和7服务器端(-server) 默认的新生代的垃圾回收器为:PS Scavenge,老年代默认的垃圾回收器为:PS MarkSweep 目前项目使用了jdk7,tomcat7,经常出现内存堆使 ...

  5. mysql在DOS环境下操作的命令

    管理员运行cmd,执行启动mysql命令:net start MySQL版本号 登录数据库:mysql -u root -p 输入密码 创建数据库:drop database if exists 数据 ...

  6. 惊呆了!Spring Boot 还能开启远程调试?

    持续原创输出,点击上方蓝字关注我 目录 前言 什么是远程调试? 为什么要远程调试? 什么是JPDA? 如何开启调试? transport server suspend address onthrow ...

  7. Filebeat 根据不同的日志设置不同的索引

    平时在物理机上使用 Filebeat 收集日志时,会编写多个 filebeat 配置文件然后启动多个 filebeat 进程来收集不同路径下的日志并设置相对应的索引.那么如果将所有的日志路径都写到一个 ...

  8. MySQL全面瓦解4:数据定义-DDL

    前言 SQL的语言分类主要包含如下几种: DDL 数据定义语言 create.drop.alter 数据定义语言 create.drop.alter 语句 . DML 数据操纵语言 insert.de ...

  9. 2. DRF 认证、权限、限流、分页、过滤、序列 化

    2.1 user/urls.py   ModelViewSet注册路由三部曲 from django.urls import include, path from user import views ...

  10. [Luogu P3959] 宝藏 (状压DP+枚举子集)

    题面 传送门:https://www.luogu.org/problemnew/show/P3959 Solution 这道题的是一道很巧妙的状压DP题. 首先,看到数据范围,应该状压DP没错了. 根 ...