netcore 集成consul

215 阅读2分钟

本文已参与「新人创作礼」活动.一起开启掘金创作之路。

netcore 集成consul

1.引用dll 

2 添加以下的类RegisterToConsulExtension

  1. 启用注册中心

app.UseConsul();

注意事项: 因注册到consul 需要ip 所以需要获取或者设置一个ip 该ip 在容器中需要设置为容器外的ip或者使用--host模式

下面的代码有获取ip的方法 兼容多种模式 ` using Autofac;
using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Service.Common.utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text.RegularExpressions;
using Utils.Common.utils;

namespace Service.Common.Extensions
{
public static class RegisterToConsulExtension
{

        ///


/// 使用Consul
///

///
///
public static IApplicationBuilder UseConsul(this IApplicationBuilder app)
{
if (ServiceUtil.Configuration["Consul:enable"] != "1")
{
return app;
}
ConsulClient client = new ConsulClient(
(ConsulClientConfiguration c) =>
{
c.Address = new Uri(ServiceUtil.Configuration["Consul:Address"]); //Consul服务中心地址
if (!String.IsNullOrEmpty(ServiceUtil.Configuration["Consul:DataCenter"]))
{
c.Datacenter = ServiceUtil.Configuration["Consul:DataCenter"]; //指定数据中心,如果未提供,则默认为代理的数据中心。
}
}
);

            //服务名
String serviceName = ServiceUtil.Configuration["WebApp:name"];

            IApplicationLifetime appLife = app.ApplicationServices.GetRequiredService();

            //获取注册到consul的端口和地址
(string IP, string Port) = getIpAndPort(app);

            // 向Consul客户端注册RestApi服务

            string checkUrl = ServiceUtil.Configuration["Consul:CheckUrl"];

            String serviceId = "{serviceName}_{IP}:{Port}";\             // 提供健康检查的HTTP接口\             var httpCheck = new AgentServiceCheck()\             {\                 DeregisterCriticalServiceAfter = TimeSpan.FromMilliseconds(1), //服务停止后多久注销\                 Interval = TimeSpan.FromSeconds(5), //服务健康检查间隔\                 Timeout = TimeSpan.FromSeconds(5), //检查超时的时间\                 HTTP = "http://{IP}:{Port}{checkUrl}" //检查的地址
};

            var registration = new AgentServiceRegistration()
{
Checks = new[] { httpCheck },
Address = IP,//本程序的IP地址
ID = serviceId,  //服务编号,不可重复
Name = serviceName,//服务名称
Port = int.Parse(Port),

            };

            LogUtils.Info($"注册到consul IP:{IP},Port:{Port},serviceName:{serviceName}");

            var result = client.Agent.ServiceRegister(registration).GetAwaiter().GetResult();

            // 服务应用停止后发注册RestApi服务
appLife.ApplicationStopping.Register(() =>
{
client.Agent.ServiceDeregister(serviceId).GetAwaiter().GetResult();
});


return app;
}

        private static (String, String) getIpAndPort(IApplicationBuilder app)
{
//为了获取命令行的参数
IConfiguration configuration = ServiceUtil.AutofacContainer.Resolve();

            //优先书序 1 命令行 2 配置 3 网站的配置 4  IServerAddressesFeature 5 获取本机的有效IP

            //命令行
string IP = configuration["regIP"];

            string Port = configuration["regPort"];

            //配置注册地址和端口
if (String.IsNullOrWhiteSpace(IP))
{
IP = ServiceUtil.Configuration["WebApp:regIP"];
if (IP == "*" || IP == "localhost" || IP == "127.0.0.0")
{
IP = "";
}
}
if (String.IsNullOrWhiteSpace(Port))
{
Port = ServiceUtil.Configuration["WebApp:regPort"];
}

            //网站的命令行
if (String.IsNullOrWhiteSpace(IP))
{
IP = configuration["ip"];
if (IP == "*" || IP == "localhost" || IP == "127.0.0.0")
{
IP = "";
}
}
if (String.IsNullOrWhiteSpace(Port))
{
Port = configuration["port"];
}


//网站配置的端口
if (String.IsNullOrWhiteSpace(IP))
{
IP = ServiceUtil.Configuration["WebApp:ip"];
if (IP == "*" || IP == "localhost" || IP == "127.0.0.0")
{
IP = "";
}
}

            if (String.IsNullOrWhiteSpace(Port))
{
Port = ServiceUtil.Configuration["WebApp:port"];
}

            // 从 IServerAddressesFeature 获取
if (String.IsNullOrEmpty(IP))
{
Uri uri = null;
try
{
uri = app.ServerFeatures.Get()
.Addresses
.Select(p => new Uri(p)).FirstOrDefault();
}
catch (Exception e)
{
LogUtils.Info($"获取默认的ip地址异常:{e.Message}");
}

                if (uri == null)
{
try
{
var features = app.Properties["server.Features"] as FeatureCollection;
uri = features.Get()
.Addresses
.Select(p => new Uri(p)).FirstOrDefault();
}
catch (Exception e)
{
LogUtils.Info($"获取默认的ip地址异常:{e.Message}");
}
}

                if (uri != null)
{
IP = uri.Host;
if (String.IsNullOrEmpty(Port))
{
Port = uri.Port.ToString();
}
}

            }

            //获取本机有效的地址
if (String.IsNullOrEmpty(IP))
{
string ignoreNetwork = ServiceUtil.Configuration["Consul:ignoreNetwork"];

                List addressIps = GetAddressIP(ignoreNetwork);
string localIp = addressIps.FirstOrDefault();
if (!String.IsNullOrWhiteSpace(localIp))
{
IP = localIp;
}
}

            if (String.IsNullOrEmpty(IP))
{
throw new Exception("服务的地址不能为空");
}
if (String.IsNullOrEmpty(Port))
{
throw new Exception("服务的端口不能为空");
}

            return (IP, Port);
}

        public static List GetAddressIP(String ignoreNetwork)
{
List ipList = new List();
//获取本地的IP地址
List regs = null;
if (!String.IsNullOrEmpty(ignoreNetwork))
{
regs = ignoreNetwork.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
}
else
{
regs = new List();
}

            List networkInterfaces = NetworkInterface.GetAllNetworkInterfaces().ToList();
foreach (NetworkInterface networkInterface in networkInterfaces)
{
if (networkInterface.OperationalStatus != OperationalStatus.Up)
{
continue;
}
IPInterfaceProperties ipInterfaceProperties = networkInterface.GetIPProperties();
UnicastIPAddressInformationCollection unicastIpAddressInformationCollection = ipInterfaceProperties.UnicastAddresses;
bool ignore = false;
foreach (var reg in regs)
{
if (Regex.Match(networkInterface.Description, reg).Success)
{
ignore = true;
break;
}
}

                if (ignore)
{
continue;
}
foreach (var unicastIpAddressInformation in unicastIpAddressInformationCollection)
{
if (unicastIpAddressInformation.Address.AddressFamily == AddressFamily.InterNetwork
&& !IPAddress.IsLoopback(unicastIpAddressInformation.Address)
&& !unicastIpAddressInformation.Address.ToString().StartsWith("169."))
{

                        ipList.Add(unicastIpAddressInformation.Address.ToString());
}
}
}

            return ipList;

        }
}
}`