.Net Core3.1 MVC + EF Core+ AutoFac+LayUI+Sqlserver的框架搭建consul服务注册和发现

     consul服务注册和发现,详细原理这里就不在说了,如果感兴趣可以单独查一下它的详细介绍,当然和他并肩的也不少,比如常用ZooKeeper。其实道理都一样,用哪个都行。

    Consul Model类:

using System;
using System.Collections.Generic;
using System.Text;

namespace Core.Net.Common.Core.Net.Core.Consul
{
   public class ConsulEntity
    {
       /// <summary>
       /// 本地ip
       /// </summary>
        public string ip { get; set; }
        /// <summary>
        /// 本地端口
        /// </summary>
        public int port { get; set; }
        /// <summary>
        /// 服务端服务实例名称
        /// </summary>
        public string ServiceName { get; set; }
        /// <summary>
        /// Consul IP
        /// </summary>
        public string ConsulIP { get; set; }
        /// <summary>
        /// Consul端口
        /// </summary>
        public int ConsulPort { get; set; }
    }
}

consul 注册类:

using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using System;
using System.Collections.Generic;
using System.Text;

namespace Core.Net.Common.Core.Net.Core.Consul
{
    /// <summary>
    /// consul
    /// </summary>
    public static class AppBuilderExtensions
    {

        /// <summary>
        /// 注册consul
        /// </summary>
        /// <param name="app"></param>
        /// <param name="lifetime"></param>
        /// <param name="serviceEntity"></param>
        /// <returns></returns>
        public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IApplicationLifetime lifetime, ConsulEntity serviceEntity)
        {
            //consul地址
            Action<ConsulClientConfiguration> configClient = (consulConfig) =>
            {
                consulConfig.Address = new Uri($"http://{serviceEntity.ConsulIP}:{ serviceEntity.ConsulPort}");
                consulConfig.Datacenter = "dc1";
            };
            //建立连接
            var consulClient = new ConsulClient(configClient);
            var httpCheck = new AgentServiceCheck()
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册
                Interval = TimeSpan.FromSeconds(10),//健康监测
                HTTP = string.Format($"http://{serviceEntity.ip}:{serviceEntity.port}/api/health/index"),//心跳检测地址
                Timeout = TimeSpan.FromSeconds(5)
            };
            //注册
            var registrtion = new AgentServiceRegistration()
            {

                Checks = new[] { httpCheck },
                ID = "CoreNet" + Guid.NewGuid().ToString(),//服务编号不可重复
                Name = serviceEntity.ServiceName,//服务名称
                Address = serviceEntity.ip,//ip地址
                Port = serviceEntity.port//端口

            };
            //注册服务
            consulClient.Agent.ServiceRegister(registrtion);

            return app;
        }

    }
}

客户端请求类:

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;

namespace Core.Net.Common.Core.Net.Core.Consul
{
  public  class ConsulHttpRequest
    {
        /// <summary>
        /// 封装 HttpClient 实例,提供 Http 调用。
        /// </summary>
        /// <param name="url">http url 的地址。</param>
        /// <returns>返回结束数据,格式:JSON。</returns>
        public static string InvokeAPI(string url)
        {
            using (HttpClient client = new HttpClient())
            {
                HttpRequestMessage message = new HttpRequestMessage();
                message.Method = HttpMethod.Get;
                message.RequestUri = new Uri(url);
                var result = client.SendAsync(message).Result;
                string conent = result.Content.ReadAsStringAsync().Result;
                return conent;
            }
        }
    }
}

     后台api接口consul服务配置:appsetting.json文件中配置

    

 startup类中中注册consul服务:

 ////注入Consul配置
            //// Configuration.ConsulRegister();
            ConsulEntity consulEntity = new ConsulEntity
            {
                ip = Configuration["ip"],
                port = int.Parse(Configuration["port"]),
                ServiceName = "CoreNet",
                ConsulIP = Configuration["Consul:IP"],
                ConsulPort = Convert.ToInt32(Configuration["Consul:Port"])
            };
            app.RegisterConsul(lifetime, consulEntity);

 还有最后一项,就是consul要每隔一段时间要做健康检查,所以api接口要添加一个健康检查控制器:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Core.Net.WebApi.Controllers.ConsulHealth
{
    /// <summary>
    /// Consul健康检查
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]

    public class HealthController : Controller
    {
        private IConfiguration _configuration;

        /// <summary>
        /// 初始化该类型的新实例。
        /// </summary>
        /// <param name="configuration">配置接口。</param>
        public HealthController(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        /// <summary>
        /// 要调用的接口。
        /// </summary>
        [HttpGet]
        public IActionResult Index()
        {
            Console.WriteLine($"This is HealhController {_configuration["port"]} Invoke");
            return Ok();
        }
    }
}

然后就是客户端如何请求,这里用web作为客户端请求:

  /// <summary>
        /// consul客户端测试
        /// </summary>
        /// <returns></returns>
        public string demo()
        {
            #region 分布式架构           

            #region  通过 Consul 服务发现来执行服务实例。ZooKeeper效果同等
            //发现服务
            string url = "http://CoreNet/api/Login/Index";

            ConsulClient client = new ConsulClient(config =>
            {
                config.Address = new Uri("http://localhost:8500/");
                config.Datacenter = "dc1";
            });
            var response = client.Agent.Services().Result.Response;
            foreach (var item in response)
            {
                Console.WriteLine("*************************************************************");
                Console.WriteLine(item.Key);
                var service = item.Value;
                Console.WriteLine($"{service.Address}--{service.Port}--{service.Service}");
                Console.WriteLine("*************************************************************");
            }
            Uri uri = new Uri(url);
            string groupName = uri.Host;
            AgentService agentService = null;

            var serviceDirectory = response.Where(s => s.Value.Service.Equals(groupName, StringComparison.OrdinalIgnoreCase)).ToArray();
            //{//1、 写死的
            //    agentService = serviceDirectory[0].Value;
            //}
            {
                //2、轮询
                if (index >= 10000)
                {
                    index = 0;
                }
                agentService = serviceDirectory[index++ % serviceDirectory.Length].Value;
            }
            // {//3、随机
            //     var indexResult = new Random(index++).Next(0, serviceDirectory.Length);
            //     agentService = serviceDirectory[indexResult].Value;
            //}
            url = $"{uri.Scheme}://{agentService.Address}:{agentService.Port}{uri.PathAndQuery}";


            #endregion

            string content = ConsulHttpRequest.InvokeAPI(url);


            #endregion
            return content;

        }

然后就是搭建测试环境了,consul的安装我以前已经做过详细介绍了,这里就不多说了,下面我要建立一个api集群,来模拟consul服务注册和发现,以本地作为测试,端口分别为3100,3200,3300:

 具体流程是:

1,启动consul组件

2,启动三个api接口向consul注册。

3,查看consul中api注册的实例。

4,web作为客户端模拟请求,查看数据。

5,关闭集群中的一个api查看consul中的集群健康度和个数。

启动consul组件:

 建立api集群,并启动api向consul注册服务实例:

查看consul中api注册的实例。

 下图是健康检查:

 模拟通过consul获取数据:

 至于验证consul发现,自己可以试一下,关闭一个api,consul会自定剔除这个有问题的api。

.Net Core
原文地址:https://www.cnblogs.com/zpy1993-09/p/15757906.html