コード例 #1
0
 public DefaultConsulConfigurationSource(ConsulConfig config, bool reloadOnChanges)
 {
     _config          = config;
     _reloadOnChanges = reloadOnChanges;
 }
コード例 #2
0
ファイル: ConsulRegistration.cs プロジェクト: zhuhj89/Adnc
 public static Uri GetServiceAddress(IApplicationBuilder app, ConsulConfig consulOption)
 {
     return(GetServiceAddressInternal(app, consulOption));
 }
コード例 #3
0
ファイル: ConsulRegistration.cs プロジェクト: zhuhj89/Adnc
        private static Uri GetServiceAddressInternal(IApplicationBuilder app, ConsulConfig consulOption)
        {
            var errorMsg       = string.Empty;
            Uri serviceAddress = default;

            if (consulOption == null)
            {
                throw new Exception("请正确配置Consul");
            }

            if (string.IsNullOrEmpty(consulOption.ConsulUrl))
            {
                throw new Exception("请正确配置ConsulUrl");
            }

            if (string.IsNullOrEmpty(consulOption.ServiceName))
            {
                throw new Exception("请正确配置ServiceName");
            }

            if (string.IsNullOrEmpty(consulOption.HealthCheckUrl))
            {
                throw new Exception("请正确配置HealthCheckUrl");
            }

            if (consulOption.HealthCheckIntervalInSecond <= 0)
            {
                throw new Exception("请正确配置HealthCheckIntervalInSecond");
            }

            //获取网卡所有Ip地址,排除回路地址
            var allIPAddress = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
                               .Select(p => p.GetIPProperties())
                               .SelectMany(p => p.UnicastAddresses)
                               .Where(p => p.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && !System.Net.IPAddress.IsLoopback(p.Address))
                               .Select(p => p.Address.ToString()).ToArray();

            //获取web服务器监听地址,也就是提供访问的地址
            var        listenAddresses = app.ServerFeatures.Get <IServerAddressesFeature>().Addresses.ToList();
            List <Uri> listenUrls      = new List <Uri>();

            listenAddresses.ForEach(a =>
            {
                var address = a.Replace("[::]", "0.0.0.0")
                              .Replace("+", "0.0.0.0")
                              .Replace("*", "0.0.0.0");

                listenUrls.Add(new Uri(address));
            });

            var logger = app.ApplicationServices.GetRequiredService <ILogger <ConsulConfig> >();


            //第一种注册方式,在配置文件中指定服务地址
            //如果配置了服务地址, 只需要检测是否在listenUrls里面即可
            if (!string.IsNullOrEmpty(consulOption.ServiceUrl))
            {
                logger.LogInformation("consulOption.ServiceUrl:{0}", consulOption.ServiceUrl);

                serviceAddress = new Uri(consulOption.ServiceUrl);
                bool isExists = listenUrls.Where(p => p.Host == serviceAddress.Host || p.Host == "0.0.0.0").Any();
                if (isExists)
                {
                    return(serviceAddress);
                }
                else
                {
                    throw new Exception($"服务{consulOption.ServiceUrl}配置错误 listenUrls={string.Join(',', (IEnumerable<Uri>)listenUrls)}");
                }
            }

            //第二种注册方式,服务地址通过docker环境变量(DOCKER_LISTEN_HOSTANDPORT)指定。
            //可以写在dockerfile文件中,也可以运行容器时指定。运行容器时指定才是最合理的,大家看各自的情况怎么处理吧。
            var dockerListenServiceUrl = Environment.GetEnvironmentVariable("DOCKER_LISTEN_HOSTANDPORT");

            if (!string.IsNullOrEmpty(dockerListenServiceUrl))
            {
                logger.LogInformation("dockerListenServiceUrl:{0}", dockerListenServiceUrl);
                serviceAddress = new Uri(dockerListenServiceUrl);
                return(serviceAddress);
            }

            //第三种注册方式,注册程序自动获取服务地址
            //本机所有可用IP与listenUrls进行匹配, 如果listenUrl是"0.0.0.0"或"[::]", 则任意IP都符合匹配
            var matches = allIPAddress.SelectMany(ip =>
                                                  listenUrls
                                                  .Where(uri => ip == uri.Host || uri.Host == "0.0.0.0")
                                                  .Select(uri => new { Protocol = uri.Scheme, ServiceIP = ip, Port = uri.Port })
                                                  ).ToList();

            //过滤无效地址
            var filteredMatches = matches.Where(p => !p.ServiceIP.Contains("0.0.0.0") &&
                                                !p.ServiceIP.Contains("localhost") &&
                                                !p.ServiceIP.Contains("127.0.0.1")
                                                );

            var finalMatches = filteredMatches.ToList();

            //没有匹配的地址,抛出异常
            if (finalMatches.Count() == 0)
            {
                throw new Exception($"没有匹配的Ip地址=[{string.Join(',', allIPAddress)}], urls={string.Join(',', (IEnumerable<Uri>)listenUrls)}");
            }

            //只有一个匹配,直接返回
            if (finalMatches.Count() == 1)
            {
                serviceAddress = new Uri($"{finalMatches[0].Protocol}://{ finalMatches[0].ServiceIP}:{finalMatches[0].Port}");
                logger.LogInformation("serviceAddress:{0}", serviceAddress);
                return(serviceAddress);
            }

            //匹配多个,直接返回第一个
            serviceAddress = new Uri($"{finalMatches[0].Protocol}://{ finalMatches[0].ServiceIP}:{finalMatches[0].Port}");
            logger.LogInformation("serviceAddress-first:{0}", serviceAddress);
            return(serviceAddress);
        }
コード例 #4
0
 public RouteLinkResponse(FabioConfig fabioConfig, ConsulConfig consulConfig)
 {
     _fabioConfig  = fabioConfig;
     _consulConfig = consulConfig;
 }
コード例 #5
0
        private static bool TryGetServiceUrl(IApplicationBuilder app, ConsulConfig consulOption, out Uri serverListenUrl, out string errorMsg)
        {
            errorMsg        = string.Empty;
            serverListenUrl = default;

            var allIPAddress = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
                               .Select(p => p.GetIPProperties())
                               .SelectMany(p => p.UnicastAddresses)
                               .Where(p => p.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && !System.Net.IPAddress.IsLoopback(p.Address))
                               .Select(p => p.Address.ToString()).ToArray();

            //docker容器部署服务,从环境变量获取ServiceUriHost与Port
            if (consulOption.IsDocker)
            {
                var listenHostAndPort = Environment.GetEnvironmentVariable("DOCKER_LISTEN_HOSTANDPORT");
                if (string.IsNullOrEmpty(listenHostAndPort))
                {
                    errorMsg = "docker部署,必须配置DOCKER_LISTEN_HOSTANDPORT环境变量";
                    return(false);
                }
                serverListenUrl = new Uri(listenHostAndPort);
                return(true);
            }

            var listenUrls = app.ServerFeatures.Get <IServerAddressesFeature>()
                             .Addresses
                             .Select(url => new Uri(url)).ToArray();

            //不是docker容器部署,并且没有配置ServiceUriHost
            if (string.IsNullOrWhiteSpace(consulOption.ServiceUrl))
            {
                // 本机所有可用IP与listenUrls进行匹配, 如果listenUrl是"0.0.0.0"或"[::]", 则任意IP都符合匹配
                var matches = allIPAddress.SelectMany(ip =>
                                                      listenUrls
                                                      .Where(uri => ip == uri.Host || uri.Host == "0.0.0.0" || uri.Host == "[::]")
                                                      .Select(uri => new { Protocol = uri.Scheme, ServiceIP = ip, Port = uri.Port })
                                                      ).ToList();

                if (matches.Count == 0)
                {
                    errorMsg = $"没有匹配的Ip地址=[{string.Join(',', allIPAddress)}], urls={string.Join(',', (IEnumerable<Uri>)listenUrls)}.";
                    return(false);
                }
                else if (matches.Count == 1)
                {
                    serverListenUrl = new Uri($"{matches[0].Protocol}://{ matches[0].ServiceIP}:{matches[0].Port}");
                    return(true);
                }
                else
                {
                    errorMsg = $"请指定ServiceUrl: {string.Join(",", matches)}.";
                    return(false);
                }
            }

            // 如果提供了对外服务的IP, 只需要检测是否在listenUrls里面即可
            var  serviceUri = new Uri(consulOption.ServiceUrl);
            bool isExists   = listenUrls.Where(p => p.Host == serviceUri.Host || p.Host == "0.0.0.0" || p.Host == "[::]").Any();

            if (isExists)
            {
                serverListenUrl = serviceUri;
                return(true);
            }
            errorMsg = $"服务Ip配置错误 urls={string.Join(',', (IEnumerable<Uri>)listenUrls)}";
            return(false);
        }
コード例 #6
0
 public static Uri GetServiceAddress(this IApplicationBuilder app, ConsulConfig config)
 {
     return(ConsulRegistration.GetServiceAddress(app, config));
 }
コード例 #7
0
        public static IConfigurationBuilder AddConsulConfiguration(this IConfigurationBuilder configurationBuilder, ConsulConfig config, bool reloadOnChanges = false)
        {
            var consulClient = new ConsulClient(client => client.Address = new Uri(config.ConsulUrl));
            var pathKeys     = config.ConsulKeyPath.Split(",", StringSplitOptions.RemoveEmptyEntries);

            foreach (var pathKey in pathKeys)
            {
                configurationBuilder.Add(new DefaultConsulConfigurationSource(consulClient, pathKey, reloadOnChanges));
            }
            return(configurationBuilder);
        }
コード例 #8
0
 public static IConfigurationBuilder AddConsulConfiguration(this IConfigurationBuilder configurationBuilder, ConsulConfig config, bool reloadOnChanges = false)
 {
     return(configurationBuilder.Add(new DefaultConsulConfigurationSource(config, reloadOnChanges)));
 }
コード例 #9
0
 /// <summary>
 /// 构造函数
 /// </summary>
 /// <param name="config"></param>
 public ConsulCheckPolicy(IOptions <ConsulConfig> config) : base(config)
 {
     _config      = config.Value;
     _tokenSource = new CancellationTokenSource();
 }
コード例 #10
0
        public static void DeregisterService(this IConsulClient consulClient, ConsulConfig consulConfig)
        {
            var registrationId = $"{consulConfig.ServiceName}-{consulConfig.ServiceId}";

            consulClient.Agent.ServiceDeregister(registrationId).Wait();
        }