zoukankan      html  css  js  c++  java
  • .NETCORE CONSUL

    .NETCORE CONSUL实现服务注册与发现-集群完整版

    标签: .netcore  consul

     
     

    一、Consul的集群介绍

       Consul Agent有两种运行模式:ServerClient。这里的Server和Client只是Consul集群层面的区分,与搭建在Cluster之上的应用服务无关, 以Server模式运行的Consul Agent节点用于维护Consul集群的状态,官方建议每个Consul Cluster至少有3个或以上的运行在Server Mode的Agent,Client节点不限。

    1、Server节点需要三台或以上机器

    2、Client节点不限

    二、Consul环境准备

    准备了三台Linux(CentOS)虚拟机(Consul Server)二台Linux(CentOS)虚拟机(Consul Client)

    Consul Server服务IP分别为:

    192.168.31.175

    192.168.31.176

    192.168.31.177

    Consul Client服务IP分别为:

    192.168.31.178

    192.168.31.179

    其中,192.168.31.175会作为leader角色,其余两台192.168.31.176和192.168.31.177会作为follower角色。当然,实际环境中leader角色不会是一个固定的,会随着环境的变化(比如Leader宕机或失联)由算法选出新的leader。在进行下面的操作会前,请确保三台节点能够相互ping通,并能够和宿主机也ping通。另外,192.168.31.178和192.168.31.179会作为client角色,并且和其余三台虚拟机互相ping通。

    三、Consul正式安装

    可以参考上一篇文章的安装方法:.netcore consul实现服务注册与发现-单台节点

    一定保证以上五台安装成功

    1、测试Consul是否安装成功

    > consul

    如下图表示成功:

    2、Consul Server服务端安装(启动与配置Consul服务)

    服务端192.168.31.175执行

    > consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul  -node=consul-175 -client=0.0.0.0  -bind=192.168.31.175 -datacenter=dc1

    服务端192.168.31.176执行

    > consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul  -node=consul-176 -client=0.0.0.0  -bind=192.168.31.176 -datacenter=dc1 -join 192.168.31.175

    服务端192.168.31.177执行

    > consul agent -server -ui -bootstrap-expect=3 -data-dir=/tmp/consul  -node=consul-177 -client=0.0.0.0  -bind=192.168.31.177 -datacenter=dc1 -join 192.168.31.175

    注:因为是集群安装,bootstrap-expect=3,以服务端的数量为准

           datacenter=dc1,三台必须在一个数据中心

          176和177的启动命令中,有一句 -join 192.168.31.175 => 有了这一句,就把176和177加入到了175所在的集群中。

      启动之后,集群就开始了Vote(投票选Leader)的过程

    命令:查看各个server的情况:

    > consul members

    命令:查看目前全部的consul的角色状态:

    > consul operator raft list-peers

    3、通过UI查看集群状态

     Consul不仅提供了丰富的命令查看集群情况,还提供了一个WebUI,默认端口8500,我们可以通过访问这个URL(eg. http://192.168.31.175:8500)得到如下图所示的WebUI:

    4、模拟Leader挂掉,查看Consul集群的新选举Leader

    直接停止192.168.31.175的服务,或者暴力直接关机

    输入命令查看服务状态

    > consul members

    查看其余两个节点的日志或者命令可以发现,consul-176被选为了新的leader

    我们也可以在次通过UI界面来查看状态:

    虽然这里192.168.31.175这个原leader节点挂掉了,但是只要超过一半的Server(这里是2/3还活着)还活着,集群是可以正常工作的,这也是为什么像Consul、ZooKeeper这样的分布式管理组件推荐我们使用3个或5个节点来部署的原因。

    注:以上也可以将.netcore项目部署在Consul Server上,但官方建议用Consul Client来关联,分别做各自的事情,互不影响。

    5、Consul Client安装

    为了节约虚拟机,目前在192.168.31.178部署.netcore项目

    1.  
      > mkdir /data/mvc
    2.  
       
    3.  
      > mkdir /data/api
    4.  
       
    5.  
      > cd /data/mvc/
    6.  
       
    7.  
      > dotnet new mvc
    8.  
       
    9.  
      > cd /data/api/
    10.  
       
    11.  
      > dotnet new webapi
    12.  
       
    13.  
      >dotnet run

    启动并运行mvc,webapi两个项目,保证能正常访问,如图正常访问

    6、将.netcore服务注册到Consul(通过配置文件来注册服务)

    1.  
      vi /etc/consul/services_config.json
    2.  
       
    3.  
      {
    4.  
       
    5.  
      "services":[
    6.  
       
    7.  
      {
    8.  
       
    9.  
      "id": "CLIENT_SERVICE_01",
    10.  
       
    11.  
      "name" : "MVCClientService",
    12.  
       
    13.  
      "tags": [
    14.  
       
    15.  
      "urlprefix-/MVCClientService01"
    16.  
       
    17.  
      ],
    18.  
       
    19.  
      "address": "192.168.31.178",
    20.  
       
    21.  
      "port": 5000,
    22.  
       
    23.  
      "checks": [
    24.  
       
    25.  
      {
    26.  
       
    27.  
      "name": "clientservice_check",
    28.  
       
    29.  
      "http": "http://192.168.31.178:5000",
    30.  
       
    31.  
      "interval": "10s",
    32.  
       
    33.  
      "timeout": "5s"
    34.  
       
    35.  
      }
    36.  
       
    37.  
      ]
    38.  
       
    39.  
      },
    40.  
       
    41.  
      {
    42.  
       
    43.  
      "id": "CLIENT_SERVICE_02",
    44.  
       
    45.  
      "name" : "APIClientService",
    46.  
       
    47.  
      "tags": [
    48.  
       
    49.  
      "urlprefix-/APIClientService02"
    50.  
       
    51.  
      ],
    52.  
       
    53.  
      "address": "192.168.31.178",
    54.  
       
    55.  
      "port": 5000,
    56.  
       
    57.  
      "checks": [
    58.  
       
    59.  
      {
    60.  
       
    61.  
      "name": "clientservice_check",
    62.  
       
    63.  
      "http": "http://192.168.31.178/api/values",
    64.  
       
    65.  
      "interval": "10s",
    66.  
       
    67.  
      "timeout": "5s"
    68.  
       
    69.  
      }
    70.  
       
    71.  
      ]
    72.  
       
    73.  
      }
    74.  
       
    75.  
      ]
    76.  
       
    77.  
      }

    在Consul Client 192.168.31.178运行命令:

    consul agent -config-dir=/etc/consul -data-dir=/tmp/consul -node=consul-178 -client=0.0.0.0 -bind=192.168.31.178 -datacenter=dc1 -join 192.168.31.175

    如下图表示正常启动,并将192.168.31.178加入到服务集群192.168.31.175中

    7、查看Consul集群状态

    可以看到192.168.31.178加入到了集群中,表示正常,还能看到.netcore的两个服务哦,也表示正常

    Consul不仅仅提供了服务注册,还提供了服务发现,我们可以通过调用其提供的API来发现服务的IP和Port。

    8、通过consul api 接口注册服务

    • 创建一个ASP.NET Core WebAPI程序

                

    • 创建一个HealthController用于Consul的健康检查    

    1.  
      [Produces("application/json")]
    2.  
       
    3.  
      [Route("api/Health")]
    4.  
       
    5.  
      public class HealthController : Controller
    6.  
       
    7.  
      {
    8.  
       
    9.  
      [HttpGet]
    10.  
       
    11.  
      public IActionResult Get() => Ok("ok");
    12.  
       
    13.  
      }

    注:Consul会通过call这个API来确认Service的健康状态。

    • 基于IApplicationBuilder写一个扩展方法,用于调用Consul API

    • 在nuge管理器中引入Consul包

    1.  
      public static class ConsulBuilderExtensions
    2.  
       
    3.  
      {
    4.  
       
    5.  
      // 服务注册
    6.  
       
    7.  
      public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IApplicationLifetime lifetime, HealthService healthService, ConsulService consulService)
    8.  
       
    9.  
      {
    10.  
       
    11.  
      var consulClient = new ConsulClient(x => x.Address = new Uri($"http://{consulService.IP}:{consulService.Port}"));//请求注册的 Consul 地址
    12.  
       
    13.  
      var httpCheck = new AgentServiceCheck()
    14.  
       
    15.  
      {
    16.  
       
    17.  
      DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册
    18.  
       
    19.  
      Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔,或者称为心跳间隔
    20.  
       
    21.  
      HTTP = $"http://{healthService.IP}:{healthService.Port}/api/health",//健康检查地址
    22.  
       
    23.  
      Timeout = TimeSpan.FromSeconds(5)
    24.  
       
    25.  
      };
    26.  
       
    27.  
      // Register service with consul
    28.  
       
    29.  
      var registration = new AgentServiceRegistration()
    30.  
       
    31.  
      {
    32.  
       
    33.  
      Checks = new[] { httpCheck },
    34.  
       
    35.  
      ID = healthService.Name + "_" + healthService.Port,
    36.  
       
    37.  
      Name = healthService.Name,
    38.  
       
    39.  
      Address = healthService.IP,
    40.  
       
    41.  
      Port = healthService.Port,
    42.  
       
    43.  
      Tags = new[] { $"urlprefix-/{healthService.Name}" }//添加 urlprefix-/servicename 格式的 tag 标签,以便 Fabio 识别
    44.  
       
    45.  
      };
    46.  
       
    47.  
      consulClient.Agent.ServiceRegister(registration).Wait();//服务启动时注册,内部实现其实就是使用 Consul API 进行注册(HttpClient发起)
    48.  
       
    49.  
      lifetime.ApplicationStopping.Register(() =>
    50.  
       
    51.  
      {
    52.  
       
    53.  
      consulClient.Agent.ServiceDeregister(registration.ID).Wait();//服务停止时取消注册
    54.  
       
    55.  
      });
    56.  
       
    57.  
      return app;
    58.  
       
    59.  
      }
    60.  
       
    61.  
      }
    62.  
       
    • 在Starup类的Configure方法中,调用此扩展方法

    1.  
      #region register this service
    2.  
       
    3.  
      ConsulService consulService = new ConsulService()
    4.  
       
    5.  
      {
    6.  
       
    7.  
      IP = Configuration["Consul:IP"],
    8.  
       
    9.  
      Port = Convert.ToInt32(Configuration["Consul:Port"])
    10.  
       
    11.  
      };
    12.  
       
    13.  
      HealthService healthService = new HealthService()
    14.  
       
    15.  
      {
    16.  
       
    17.  
      IP = Configuration["Service:IP"],
    18.  
       
    19.  
      Port = Convert.ToInt32(Configuration["Service:Port"]),
    20.  
       
    21.  
      Name = Configuration["Service:Name"],
    22.  
       
    23.  
      };
    24.  
       
    25.  
      app.RegisterConsul(lifetime, healthService, consulService);
    26.  
       
    27.  
      #endregion
    • 其中用到了appSettings.json配置文件,其定义如下:

    1.  
      "Service": {
    2.  
       
    3.  
      "Name": "DMSWebAPITest",
    4.  
       
    5.  
      "IP": "localhost",
    6.  
       
    7.  
      "Port": "5001"
    8.  
       
    9.  
      },
    10.  
       
    11.  
      "Consul": {
    12.  
       
    13.  
      "IP": "localhost",
    14.  
       
    15.  
      "Port": "8500"
    16.  
       
    17.  
      }
    • 其中ConsulService类定义如下:

    1.  
      public class ConsulService
    2.  
       
    3.  
      {
    4.  
       
    5.  
      public string IP { get; set; }
    6.  
       
    7.  
      public int Port { get; set; }
    8.  
       
    9.  
      }
    • 其中HealthService类定义如下:

    1.  
      public class HealthService
    2.  
       
    3.  
      {
    4.  
       
    5.  
      public string Name { get; set; }
    6.  
       
    7.  
      public string IP { get; set; }
    8.  
       
    9.  
      public int Port { get; set; }
    10.  
       
    11.  
       
    12.  
       
    13.  
      }
    • 确保HealthController的API能正常访问,以便做健康检查

    • 成功运行后,查看Consul集群的状态,UI界面

    Exceptionless作分布式日志开源框架,Log4net,NLog,Autofac属性注入,Consul API接口服务注册实例等开源地址:https://github.com/hailang2ll/DMS

    作者:Leo_wl
             
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    版权信息
  • 相关阅读:
    springmvc完成ajax功能以及返回字符串出现乱码的解决方法
    修改controller保存数据的作用域
    controller的数据保存
    sringmvc接收日期参数
    常见的几种HandlerMapping
    springmvc的流程
    mvc的流程
    为实体类定义别名以及批量为某个包里面的实体类设置别名
    添加日志文件
    JSP页面添加当前时间
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/15493030.html
Copyright © 2011-2022 走看看