Beispiel #1
0
        public void Agent_Checks_ServiceBound()
        {
            var c = ClientTest.MakeClient();

            var serviceReg = new AgentServiceRegistration()
            {
                Name = "redis"
            };
            c.Agent.ServiceRegister(serviceReg);

            var reg = new AgentCheckRegistration()
            {
                Name = "redischeck",
                ServiceID = "redis",
                TTL = TimeSpan.FromSeconds(15)
            };
            c.Agent.CheckRegister(reg);

            var checks = c.Agent.Checks();
            Assert.IsTrue(checks.Response.ContainsKey("redischeck"));
            Assert.AreEqual(checks.Response["redischeck"].ServiceID, "redis");

            c.Agent.CheckDeregister("redischeck");
            c.Agent.ServiceDeregister("redis");
        }
Beispiel #2
0
        public async Task Agent_Services()
        {
            var client = new ConsulClient();
            var registration = new AgentServiceRegistration()
            {
                Name = "foo",
                Tags = new[] { "bar", "baz" },
                Port = 8000,
                Check = new AgentServiceCheck
                {
                    TTL = TimeSpan.FromSeconds(15)
                }
            };

            await client.Agent.ServiceRegister(registration);

            var services = await client.Agent.Services();
            Assert.True(services.Response.ContainsKey("foo"));

            var checks = await client.Agent.Checks();
            Assert.True(checks.Response.ContainsKey("service:foo"));

            Assert.Equal(CheckStatus.Critical, checks.Response["service:foo"].Status);

            await client.Agent.ServiceDeregister("foo");
        }
        public async Task Health_Checks()
        {
            var client = new ConsulClient();

            var registration = new AgentServiceRegistration()
            {
                Name = "foo",
                Tags = new[] { "bar", "baz" },
                Port = 8000,
                Check = new AgentServiceCheck
                {
                    TTL = TimeSpan.FromSeconds(15)
                }
            };
            try
            {
                await client.Agent.ServiceRegister(registration);
                var checks = await client.Health.Checks("foo");
                Assert.NotEqual((ulong)0, checks.LastIndex);
                Assert.NotEqual(0, checks.Response.Length);
            }
            finally
            {
                await client.Agent.ServiceDeregister("foo");
            }
        }
Beispiel #4
0
        public void Health_Checks()
        {
            var c = ClientTest.MakeClient();

            var reg = new AgentServiceRegistration()
            {
                Name = "foo",
                Tags = new[] {"bar", "baz"},
                Port = 8000,
                Check = new AgentServiceCheck
                {
                    TTL = TimeSpan.FromSeconds(15)
                }
            };
            try
            {
                c.Agent.ServiceRegister(reg);
                var checks = c.Health.Checks("foo");
                Assert.AreNotEqual(0, checks.LastIndex);
                Assert.AreNotEqual(0, checks.Response.Length);
            }
            finally
            {
                c.Agent.ServiceDeregister("foo");
            }
        }
Beispiel #5
0
        public AgentServiceRegistration CreateService()
        {
            AgentServiceRegistration serviceRegistration = new AgentServiceRegistration
            {
                Name = _appname
                //Port = _apport,
                //Address = _appadress
                //Check = CheckTtl()
            };

            return serviceRegistration;
        }
        public Task Publish(string type, string data)
        {
            var client = GetConsulClient();

            var registration = new AgentServiceRegistration()
            {
                ID = $"{owner}:{type}",
                Name = ServiceName,
                Tags = new[] { data}
            };

            client.Agent.ServiceRegister(registration);
            return Task.FromResult(0);
        }
        /// <summary>
        /// Registers the specified client.
        /// </summary>
        /// <param name="client">The client.</param>
        public void Register(Client client)
        {
            var gatewayConfiguration = HttpGatewayConfiguration.GetConfiguration();
            foreach (OrderAPIServerElement serverDefinition in gatewayConfiguration.OrderServiceConfiguration.Servers)
            {
                var registration = new AgentServiceRegistration()
                {
                    ID =serverDefinition.Id,
                    Name = serverDefinition.Name,
                    Address = serverDefinition.Address,
                    Port = serverDefinition.Port,
                    Tags = new []{"Orders"}
                };

                //clear any old registration - we don't respond to services running/not running in this version
                client.Agent.ServiceDeregister(registration.ID);
                client.Agent.ServiceRegister(registration);
            }
        }
Beispiel #8
0
 public AgentServiceRegistrationHostedService(IConsulClient consulClient, AgentServiceRegistration serviceRegistration, ILogger <AgentServiceRegistrationHostedService> logger)
 {
     _consulClient        = consulClient;
     _serviceRegistration = serviceRegistration;
     _logger = logger;
 }
        public static IApplicationBuilder UseConsul(this IApplicationBuilder app)
        {
            // 获取主机生命周期管理接口
            var lifetime = app.ApplicationServices.GetRequiredService <IHostApplicationLifetime>();

            // 获取服务配置项
            var serviceOptions = app.ApplicationServices.GetRequiredService <IOptions <ConsulServiceOptions> >().Value;

            var config = app.ApplicationServices.GetRequiredService <IConfiguration>();

            // 服务ID必须保证唯一
            serviceOptions.ServiceId = Guid.NewGuid().ToString();

            var consulClient = new ConsulClient(configuration =>
            {
                //服务注册的地址,集群中任意一个地址
                configuration.Address = new Uri(serviceOptions.ConsulAddress);
            });

            // 使用参数配置服务注册地址
            var address = config["address"];

            if (string.IsNullOrEmpty(address))
            {
                // 获取当前服务地址和端口
                var features = app.Properties["server.Features"] as FeatureCollection;
                address = features?.Get <IServerAddressesFeature>().Addresses.First();
            }
            var uri = new Uri(address);

            // 节点服务注册对象
            var registration = new AgentServiceRegistration()
            {
                ID      = serviceOptions.ServiceId,
                Name    = serviceOptions.ServiceName,// 服务名
                Address = uri.Host,

                Port  = uri.Port, // 服务端口
                Check = new AgentServiceCheck
                {
                    // 注册超时
                    Timeout = TimeSpan.FromSeconds(5),
                    // 服务停止多久后注销服务
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                    // 健康检查地址
                    HTTP = $"{uri.Scheme}://{uri.Host}:{uri.Port}{serviceOptions.HealthCheck}",
                    // 健康检查时间间隔
                    Interval = TimeSpan.FromSeconds(10),
                }
            };

            // 注册服务
            consulClient.Agent.ServiceRegister(registration).Wait();

            // 应用程序终止时,注销服务
            lifetime.ApplicationStopping.Register(() =>
            {
                consulClient.Agent.ServiceDeregister(serviceOptions.ServiceId).Wait();
            });

            return(app);
        }
Beispiel #10
0
        public async Task Agent_SetTTLStatus()
        {
            var client = new ConsulClient();
            var registration = new AgentServiceRegistration()
            {
                Name = "foo",
                Check = new AgentServiceCheck
                {
                    TTL = TimeSpan.FromSeconds(15)
                }
            };
            await client.Agent.ServiceRegister(registration);

            await client.Agent.WarnTTL("service:foo", "warning");
            var checks = await client.Agent.Checks();
            Assert.Contains("service:foo", checks.Response.Keys);
            Assert.Equal(CheckStatus.Warning, checks.Response["service:foo"].Status);
            Assert.Equal("warning", checks.Response["service:foo"].Output);

            await client.Agent.PassTTL("service:foo", "passing");
            checks = await client.Agent.Checks();
            Assert.Contains("service:foo", checks.Response.Keys);
            Assert.Equal(CheckStatus.Passing, checks.Response["service:foo"].Status);
            Assert.Equal("passing", checks.Response["service:foo"].Output);

            await client.Agent.FailTTL("service:foo", "failing");
            checks = await client.Agent.Checks();
            Assert.Contains("service:foo", checks.Response.Keys);
            Assert.Equal(CheckStatus.Critical, checks.Response["service:foo"].Status);
            Assert.Equal("failing", checks.Response["service:foo"].Output);

            await client.Agent.UpdateTTL("service:foo", "foo", TTLStatus.Pass);
            checks = await client.Agent.Checks();
            Assert.Contains("service:foo", checks.Response.Keys);
            Assert.Equal(CheckStatus.Passing, checks.Response["service:foo"].Status);
            Assert.Equal("foo", checks.Response["service:foo"].Output);

            await client.Agent.UpdateTTL("service:foo", "foo warning", TTLStatus.Warn);
            checks = await client.Agent.Checks();
            Assert.Contains("service:foo", checks.Response.Keys);
            Assert.Equal(CheckStatus.Warning, checks.Response["service:foo"].Status);
            Assert.Equal("foo warning", checks.Response["service:foo"].Output);

            await client.Agent.UpdateTTL("service:foo", "foo failing", TTLStatus.Critical);
            checks = await client.Agent.Checks();
            Assert.Contains("service:foo", checks.Response.Keys);
            Assert.Equal(CheckStatus.Critical, checks.Response["service:foo"].Status);
            Assert.Equal("foo failing", checks.Response["service:foo"].Output);

            await client.Agent.ServiceDeregister("foo");
        }
Beispiel #11
0
        public void Agent_SetTTLStatus()
        {
            var c = ClientTest.MakeClient();
            var reg = new AgentServiceRegistration()
            {
                Name = "foo",
                Check = new AgentServiceCheck
                {
                    TTL = TimeSpan.FromSeconds(15)
                }
            };
            c.Agent.ServiceRegister(reg);

            c.Agent.WarnTTL("service:foo", "test");

            var checks = c.Agent.Checks();
            Assert.IsTrue(checks.Response.ContainsKey("service:foo"));

            Assert.AreEqual(checks.Response["service:foo"].Status, CheckStatus.Warning);

            c.Agent.ServiceDeregister("foo");
        }
Beispiel #12
0
        public void Agent_Services_CheckPassing()
        {
            var c = ClientTest.MakeClient();
            var reg = new AgentServiceRegistration()
            {
                Name = "foo",
                Tags = new[] { "bar", "baz" },
                Port = 8000,
                Check = new AgentServiceCheck
                {
                    TTL = TimeSpan.FromSeconds(15),
                    Status = CheckStatus.Passing
                }
            };
            c.Agent.ServiceRegister(reg);

            var services = c.Agent.Services();
            Assert.IsTrue(services.Response.ContainsKey("foo"));

            var checks = c.Agent.Checks();
            Assert.IsTrue(checks.Response.ContainsKey("service:foo"));

            Assert.AreEqual(checks.Response["service:foo"].Status, CheckStatus.Passing);

            c.Agent.ServiceDeregister("foo");
        }
        private void RegisterService()
        {
            var client = new Client();

            var configuration = OrderServerConfiguration.GetConfiguration();
            var registration = new AgentServiceRegistration()
            {
                ID = configuration.Server.Id,
                Name = configuration.Server.Name,
                Address = configuration.Server.Address,
                Port = configuration.Server.Port,
                Tags = new[] { "Orders" }
            };

            //clear any old registration - we don't respond to services running/not running in this version
            client.Agent.ServiceDeregister(registration.ID);
            client.Agent.ServiceRegister(registration);
        }
        /// <summary>
        /// 使用consul
        /// 默认的健康检查接口格式是 http://host:port/HealthCheck
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseConsul(this IApplicationBuilder app)
        {
            IConsulClient        consul  = app.ApplicationServices.GetRequiredService <IConsulClient>();
            IApplicationLifetime appLife = app.ApplicationServices.GetRequiredService <IApplicationLifetime>();
            IOptions <ServiceRegisterOptions> serviceOptions = app.ApplicationServices.GetRequiredService <IOptions <ServiceRegisterOptions> >();

            //TODO: 这两句代码,必须使用Microsoft.NETCore.App 2.1 的程序集
            //var features = app.Properties["server.Features"] as FeatureCollection;
            //var port = new Uri(features.Get<IServerAddressesFeature>().Addresses.FirstOrDefault()).Port; //获取端口
            var port    = serviceOptions.Value.ServicePort;      //获取配置文件的端口
            var address = serviceOptions.Value.ServiceIpAddress; //获取配置文件的IP地址

            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine($"application port is :{port}");

            var addressIpv4Hosts = NetworkInterface.GetAllNetworkInterfaces()
                                   .OrderByDescending(c => c.Speed)
                                   .Where(c => c.NetworkInterfaceType != NetworkInterfaceType.Loopback && c.OperationalStatus == OperationalStatus.Up);

            foreach (var item in addressIpv4Hosts)
            {
                if (string.IsNullOrEmpty(address))
                {
                    //这是ipv4的ip地址
                    var firstIpV4Address = item.GetIPProperties().UnicastAddresses.Where(c => c.Address.AddressFamily == AddressFamily.InterNetwork).Select(c => c.Address).FirstOrDefault()?.ToString();
                    if (string.IsNullOrEmpty(firstIpV4Address))
                    {
                        continue;
                    }
                    if (firstIpV4Address.Contains("localhost"))
                    {
                        continue;
                    }
                    address = firstIpV4Address;
                }

                var serviceId = $"{serviceOptions.Value.ServiceName}_{address}:{port}";
                var httpCheck = new AgentServiceCheck()
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1),
                    Interval = TimeSpan.FromSeconds(10),                             //健康检查间隔10s,原来是30s
                    HTTP     = $"{Uri.UriSchemeHttp}://{address}:{port}/HealthCheck" //这个是默认健康检查接口
                };

                var registration = new AgentServiceRegistration()
                {
                    Checks  = new[] { httpCheck },
                    Address = address,
                    ID      = serviceId,
                    Name    = serviceOptions.Value.ServiceName,
                    Port    = port
                };

                bool retry = true;
                while (retry)
                {
                    try
                    {
                        consul.Agent.ServiceRegister(registration).GetAwaiter().GetResult();
                        retry = false;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }
                    finally
                    {
                        Thread.Sleep(1000 * 5);
                    }
                }

                //当服务停止后想consul发送的请求
                appLife.ApplicationStopping.Register(() =>
                {
                    consul.Agent.ServiceDeregister(serviceId).GetAwaiter().GetResult();
                });

                Console.ForegroundColor = ConsoleColor.Blue;
                Console.WriteLine($"health check service:{httpCheck.HTTP}");
            }

            return(app);
        }
Beispiel #15
0
        public async Task Agent_ServiceMaintenance()
        {
            var client = new ConsulClient();

            var serviceReg = new AgentServiceRegistration()
            {
                Name = "redis"
            };
            await client.Agent.ServiceRegister(serviceReg);

            await client.Agent.EnableServiceMaintenance("redis", "broken");

            var checks = await client.Agent.Checks();
            var found = false;
            foreach (var check in checks.Response)
            {
                if (check.Value.CheckID.Contains("maintenance"))
                {
                    found = true;
                    Assert.Equal(CheckStatus.Critical, check.Value.Status);
                    Assert.Equal("broken", check.Value.Notes);
                }
            }
            Assert.True(found);

            await client.Agent.DisableServiceMaintenance("redis");

            checks = await client.Agent.Checks();
            foreach (var check in checks.Response)
            {
                Assert.False(check.Value.CheckID.Contains("maintenance"));
            }

            await client.Agent.ServiceDeregister("redis");
        }
Beispiel #16
0
        /// <summary>
        /// use Consul
        /// 使用consul
        /// The default health check interface format is http://host:port/HealthCheck
        /// 默认的健康检查接口格式是 http://host:port/HealthCheck
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseConsul(this IApplicationBuilder app)
        {
            IConsulClient        consul  = app.ApplicationServices.GetRequiredService <IConsulClient>();
            IApplicationLifetime appLife = app.ApplicationServices.GetRequiredService <IApplicationLifetime>();
            IOptions <ServiceDiscoveryOptions> serviceOptions = app.ApplicationServices.GetRequiredService <IOptions <ServiceDiscoveryOptions> >();
            var features = app.Properties["server.Features"] as FeatureCollection;
            var aa       = features.Get <IServerAddressesFeature>();
            //var port = new Uri(features.Get<IServerAddressesFeature>()
            //    .Addresses
            //    .FirstOrDefault()).Port;
            var port = new Uri(Configuration.GetValue(typeof(string), "Host").ToString()).Port;

            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine($"application port is :{port}");
            var addressIpv4Hosts = NetworkInterface.GetAllNetworkInterfaces()
                                   .OrderByDescending(c => c.Speed)
                                   .Where(c => c.NetworkInterfaceType != NetworkInterfaceType.Loopback && c.OperationalStatus == OperationalStatus.Up);

            foreach (var item in addressIpv4Hosts)
            {
                var props = item.GetIPProperties();
                //this is ip for ipv4
                //这是ipv4的ip地址
                var firstIpV4Address = props.UnicastAddresses
                                       .Where(c => c.Address.AddressFamily == AddressFamily.InterNetwork)
                                       .Select(c => c.Address)
                                       .FirstOrDefault().ToString();
                var serviceId = $"{serviceOptions.Value.ServiceName}_{firstIpV4Address}:{port}";

                var httpCheck = new AgentServiceCheck()
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1),
                    Interval = TimeSpan.FromSeconds(10),
                    //this is default health check interface
                    //这个是默认健康检查接口
                    HTTP = $"{Uri.UriSchemeHttp}://{firstIpV4Address}:{port}/HealthCheck",
                };

                var registration = new AgentServiceRegistration()
                {
                    Checks  = new[] { httpCheck },
                    Address = firstIpV4Address.ToString(),
                    ID      = serviceId,
                    Name    = serviceOptions.Value.ServiceName,
                    Port    = port,
                    Tags    = new string[] { serviceOptions.Value.ServiceName }
                };

                consul.Agent.ServiceRegister(registration).GetAwaiter().GetResult();

                //send consul request after service stop
                //当服务停止后想consul发送的请求
                appLife.ApplicationStopping.Register(() =>
                {
                    consul.Agent.ServiceDeregister(serviceId).GetAwaiter().GetResult();
                });

                Console.ForegroundColor = ConsoleColor.Blue;
                Console.WriteLine($"health check service:{httpCheck.HTTP}");
            }

            #region 注册本地地址
            ////register localhost address
            ////注册本地地址
            //var localhostregistration = new AgentServiceRegistration()
            //{
            //    Checks = new[] { new AgentServiceCheck()
            //    {
            //        DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1),
            //        Interval = TimeSpan.FromSeconds(15),
            //        HTTP = $"{Uri.UriSchemeHttp}://localhost:{port}/HealthCheck",
            //    } },
            //    Address = "localhost",
            //    ID = $"{serviceOptions.Value.ServiceName}_localhost:{port}",
            //    Name = serviceOptions.Value.ServiceName,
            //    Port = port
            //};

            //consul.Agent.ServiceRegister(localhostregistration).GetAwaiter().GetResult();

            ////send consul request after service stop
            ////当服务停止后想consul发送的请求
            //appLife.ApplicationStopping.Register(() =>
            //{
            //    consul.Agent.ServiceDeregister(localhostregistration.ID).GetAwaiter().GetResult();
            //});
            #endregion

            app.Map("/HealthCheck", s =>
            {
                s.Run(async context =>
                {
                    await context.Response.WriteAsync("ok");
                });
            });
            return(app);
        }
Beispiel #17
0
 public ConsulServiceRegistrar(ILoggerFactory log, IConsulClient client, AgentServiceRegistration serviceRegistration)
 {
     _log    = log.CreateLogger(nameof(ConsulServiceRegistrar));
     _client = client;
     _serviceRegistration = serviceRegistration;
 }
Beispiel #18
0
        protected override Func <CancellationToken, Task> CreateRegisterJob()
        {
            var id = GetId();

            if (!_addressService.TryGetAddress(out Uri uri))
            {
                return(null);
            }

            var registration = new AgentServiceRegistration
            {
                ID      = id,
                Name    = _appName,
                Address = uri.Host,
                Port    = uri.Port,
                Meta    = new Dictionary <string, string> {
                    { "scheme", uri.Scheme }
                },
                Check = new AgentServiceCheck
                {
                    TCP      = $"{uri.Host}:{uri.Port}",
                    Interval = new TimeSpan(0, 0, 10),
                    Timeout  = new TimeSpan(0, 0, 3),
                    DeregisterCriticalServiceAfter = new TimeSpan(0, 0, 20),
                }
            };

            AgentServiceRegistration registrationMetrics = null;

            if (_withMetricsPort)
            {
                registrationMetrics = new AgentServiceRegistration
                {
                    ID      = $"{id}-metrics",
                    Name    = _appName,
                    Address = uri.Host,
                    Port    = uri.Port * 10,
                    Meta    = new Dictionary <string, string> {
                        { "scheme", uri.Scheme }
                    },
                    Tags  = new[] { "metrics" },
                    Check = new AgentServiceCheck
                    {
                        TCP      = $"{uri.Host}:{uri.Port}",
                        Interval = new TimeSpan(0, 0, 10),
                        Timeout  = new TimeSpan(0, 0, 3),
                        DeregisterCriticalServiceAfter = new TimeSpan(0, 0, 20),
                    }
                }
            }
            ;

            return(async cancellationToken =>
            {
                await _consul.Agent.ServiceRegister(registration, cancellationToken);

                _logger.LogInformation(
                    $"Register service [{registration.Name}] at [{registration.Address}:{registration.Port}] as [{registration.ID}]");

                if (registrationMetrics == null)
                {
                    return;
                }

                await _consul.Agent.ServiceRegister(registrationMetrics, cancellationToken);

                _logger.LogInformation(
                    $"Register service metrics [{registration.Name}] at [{registration.Address}:{registration.Port}] as [{registration.ID}]");
            });
        }
    }
Beispiel #19
0
 public static void Registor(AgentServiceRegistration agentService)
 {
     AgentServices.Add(agentService);
     ConsulClientInstance.Agent.ServiceRegister(agentService);
 }
Beispiel #20
0
        public void Agent_Services_CheckTTLNote()
        {
            var client = new Client();
            var registration = new AgentServiceRegistration()
            {
                Name = "foo",
                Tags = new[] { "bar", "baz" },
                Port = 8000,
                Check = new AgentServiceCheck
                {
                    TTL = TimeSpan.FromSeconds(15),
                    Status = CheckStatus.Critical
                }
            };
            client.Agent.ServiceRegister(registration);

            var services = client.Agent.Services();
            Assert.IsTrue(services.Response.ContainsKey("foo"));

            var checks = client.Agent.Checks();
            Assert.IsTrue(checks.Response.ContainsKey("service:foo"));

            Assert.AreEqual(CheckStatus.Critical, checks.Response["service:foo"].Status);

            client.Agent.PassTTL("service:foo", "ok");
            checks = client.Agent.Checks();

            Assert.IsTrue(checks.Response.ContainsKey("service:foo"));
            Assert.AreEqual(CheckStatus.Passing, checks.Response["service:foo"].Status);
            Assert.AreEqual("ok", checks.Response["service:foo"].Output);

            client.Agent.ServiceDeregister("foo");
        }
Beispiel #21
0
#pragma warning disable CS1998
        private async ValueTask <AgentServiceRegistration> BuildRegisterationRequestAsync()
#pragma warning restore CS1998
        {
            if (registration != null)
            {
                return(registration);
            }
            var serviceId   = _serviceHelper.GetRunningServiceId();
            var serviceName = _serviceHelper.GetRunningServiceName();
            var serviceTags = _serviceHelper.GetRunningServiceTags().ToArray();

            var address = "http://localhost:5000";

            IPAddress addr = null;

            foreach (var addressString in _serverAddressesFeature.Addresses)
            {
                Logger.LogTrace($"Service discovery:Found address:{addressString}");
                if (addr != null)
                {
                    break;
                }

                address = addressString;

                if (address == null)
                {
                    continue;
                }

                if (address.StartsWith("http://+:") || address.StartsWith("https://+:"))
                {
                    address = address.Replace("+", "[::]");
                }

                if (!Uri.TryCreate(address, UriKind.Absolute, out var uri))
                {
                    continue;
                }

                if (IPAddress.TryParse(uri.DnsSafeHost, out addr))
                {
                    if (IPAddress.Loopback.Equals(addr) || IPAddress.IPv6Loopback.Equals(addr))
                    {
                        addr = null;
                        continue;
                    }
                    if (IPAddress.Any.Equals(addr) || IPAddress.IPv6Any.Equals(addr))
                    {
                        addr = IPAddress.Loopback;
                        break;
                    }
                }
                else
                {
                    addr = null;
                }
            }

            Logger.LogTrace($"Service discovery:Current IP address is : {addr}");
            Logger.LogTrace($"Service discovery:Nearest address:{address}");
            if (addr == null)
            {
                Logger.LogCritical($"Service discovery:No usable IP address.(0)");
                return(null);
            }

            if (!Uri.TryCreate(address, UriKind.Absolute, out var addressUri))
            {
                Logger.LogCritical($"Service discovery:Cannot build a usable URI.");
                return(null);
            }
            var hostNameOrAddress = string.Empty;

            if (IPAddress.Loopback.Equals(addr) || IPAddress.IPv6Loopback.Equals(addr))
            {
                //// lo(v6)
                hostNameOrAddress = Dns.GetHostName();
            }
            else
            {
                hostNameOrAddress = addr.ToString();
            }
            Logger.LogTrace($"Service discovery:Current host name is : {hostNameOrAddress}");
            Logger.LogTrace($"Service discovery:Current address uri is : {addressUri}");
            var ipEntry = await Dns.GetHostEntryAsync(hostNameOrAddress);

            Logger.LogTrace($"Service discovery:Found host name is : {ipEntry.HostName}");
            var addressListString = ipEntry.AddressList.Aggregate(new StringBuilder(), (sb, s) => sb.Append(s).Append(","));

            Logger.LogTrace($"Service discovery:Found all addresses are : {addressListString}");
            bool isIpv6 = false;

            var ipAddress = ipEntry.AddressList
                            .Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                            .Where(ip => !IPAddress.Any.Equals(ip))
                            .Where(ip => !IPAddress.Loopback.Equals(ip))
                            .Where(ip => !IPAddress.None.Equals(ip))
                            .FirstOrDefault();

            if (ipAddress == null)
            {
                isIpv6    = true;
                ipAddress = ipEntry.AddressList
                            .Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                            .Where(ip => !IPAddress.IPv6Any.Equals(ip))
                            .Where(ip => !IPAddress.IPv6Loopback.Equals(ip))
                            .Where(ip => !IPAddress.IPv6None.Equals(ip))
                            .FirstOrDefault();
            }

            if (ipAddress == null)
            {
                Logger.LogCritical($"Service discovery:No usable IP address.(1)");
                return(null);
            }
            var host = ipAddress.ToString();

            if (isIpv6)
            {
                host = $"[{host}]";
            }

            address = $"{addressUri.Scheme}://{host}:{addressUri.Port}";

            Logger.LogTrace($"Service discovery:Try resolving address:{address}");

            if (!Uri.TryCreate(address, UriKind.Absolute, out addressUri))
            {
                Logger.LogCritical($"Service discovery:No usable IP address.(2)");
                return(null);
            }
            Logger.LogTrace($"Service discovery:The new address uri is :{addressUri}");
            var checks = _healthCheckHelper.GetHeathCheckInfo()
                         .Select(info => new AgentServiceCheck
            {
                HTTP     = address + info.Path,
                Interval = TimeSpan.FromSeconds(info.Interval),
                Status   = HealthStatus.Passing
            })
                         .ToArray();

            var request = registration = new AgentServiceRegistration
            {
                ID      = serviceId,
                Name    = serviceName,
                Address = addressUri.DnsSafeHost,
                Port    = addressUri.Port,
                Tags    = serviceTags,
                Checks  = checks
            };

            return(request);
        }
        public static IApplicationBuilder RegisterWithConsul(
            this IApplicationBuilder app,
            IHostApplicationLifetime lifetime,
            Action <ServiceRegistrationConfiguration, IServiceProvider> configurator = null
            )
        {
            if (lifetime == null)
            {
                throw new ArgumentNullException(nameof(lifetime));
            }

            // Retrieve Consul client from DI
            var consulClient = app.ApplicationServices.GetRequiredService <IConsulClient>();

            // Setup logger
            var loggingFactory = app.ApplicationServices
                                 .GetRequiredService <ILoggerFactory>();
            var logger = loggingFactory.CreateLogger <IApplicationBuilder>();

            // Get server IP address
            var addresses = app.ServerFeatures.Get <IServerAddressesFeature>();
            var address   = addresses.Addresses.First();

            Console.WriteLine($"The api address is :{address}");
            logger.LogWarning($"The api address is :{address}");
            // Register service with consul
            var uri = new Uri(address);

            var serviceRegistration =
                app.ApplicationServices.GetService <IOptions <ServiceRegistrationConfiguration> >().Value;

            configurator?.Invoke(serviceRegistration, app.ApplicationServices);

            var health = new AgentCheckRegistration
            {
                HTTP     = $"{uri.Scheme}://{uri.Host}:{uri.Port}{serviceRegistration.HealthCheckEndpoint}",
                Notes    = $"Checks {serviceRegistration.HealthCheckEndpoint} on {uri.Host}",
                Timeout  = TimeSpan.FromSeconds(3),
                Interval = TimeSpan.FromSeconds(30),
                DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1)
            };

            var registration = new AgentServiceRegistration
            {
                Checks = new AgentServiceCheck[] { health },

                ID      = $"{serviceRegistration.ServiceId}-{uri.Port}",
                Name    = serviceRegistration.ServiceName,
                Address = uri.Host,
                Port    = uri.Port,
                Tags    = serviceRegistration.Tags ?? new[] { serviceRegistration.ServiceName }
            };

            logger.LogInformation("Registering with Consul");

            consulClient.Agent.ServiceDeregister(registration.ID).Wait();
            consulClient.Agent.ServiceRegister(registration).Wait();

            // handle De-registration of the service
            // upon application shutdown, graceful shutdown not killing
            lifetime.ApplicationStopping.Register(() =>
            {
                logger.LogInformation("De-registering from Consul");
                consulClient.Agent.ServiceDeregister(registration.ID).Wait();
            });

            return(app);
        }
        private static AgentServiceRegistration CreateConsulAgentRegistration(this IFixerBuilder builder,
                                                                              ConsulOptions options)
        {
            var enabled       = options.Enabled;
            var consulEnabled = Environment.GetEnvironmentVariable("CONSUL_ENABLED")?.ToLowerInvariant();

            if (!string.IsNullOrWhiteSpace(consulEnabled))
            {
                enabled = consulEnabled == "true" || consulEnabled == "1";
            }

            if (!enabled)
            {
                return(null);
            }

            if (string.IsNullOrWhiteSpace(options.Address))
            {
                throw new ArgumentException("Consul address can not be empty.",
                                            nameof(options.PingEndpoint));
            }

            var uniqueId = string.Empty;

            using (var serviceProvider = builder.Services.BuildServiceProvider())
            {
                uniqueId = serviceProvider.GetRequiredService <IServiceId>().Id;
            }

            var pingInterval        = options.PingInterval <= 0 ? 5 : options.PingInterval;
            var removeAfterInterval = options.RemoveAfterInterval <= 0 ? 10 : options.RemoveAfterInterval;

            var registration = new AgentServiceRegistration
            {
                Name    = options.Service,
                ID      = $"{options.Service}:{uniqueId}",
                Address = options.Address,
                Port    = options.Port
            };

            if (!options.PingEnabled)
            {
                return(registration);
            }


            var scheme = options.Address.StartsWith("http", StringComparison.InvariantCultureIgnoreCase)
                ? string.Empty
                : "http://";
            var check = new AgentServiceCheck
            {
                Interval = TimeSpan.FromSeconds(pingInterval),
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(removeAfterInterval),
                HTTP = $"{scheme}{options.Address}{(options.Port > 0 ? $":{options.Port}" : string.Empty)}/" +
                       $"{options.PingEndpoint}"
            };

            registration.Checks = new[] { check };

            return(registration);
        }
Beispiel #24
0
        public void Agent_ServiceAddress()
        {
            var c = ClientTest.MakeClient();
            var reg1 = new AgentServiceRegistration()
            {
                Name = "foo1",
                Port = 8000,
                Address = "192.168.0.42"
            };
            var reg2 = new AgentServiceRegistration()
            {
                Name = "foo2",
                Port = 8000
            };

            c.Agent.ServiceRegister(reg1);
            c.Agent.ServiceRegister(reg2);

            var services = c.Agent.Services();
            Assert.IsTrue(services.Response.ContainsKey("foo1"));
            Assert.IsTrue(services.Response.ContainsKey("foo2"));
            Assert.AreEqual(services.Response["foo1"].Address, "192.168.0.42");
            Assert.IsTrue(string.IsNullOrEmpty(services.Response["foo2"].Address));

            c.Agent.ServiceDeregister("foo1");
            c.Agent.ServiceDeregister("foo2");
        }
Beispiel #25
0
        public async Task Agent_SetTTLStatus()
        {
            var client = new ConsulClient();
            var registration = new AgentServiceRegistration()
            {
                Name = "foo",
                Check = new AgentServiceCheck
                {
                    TTL = TimeSpan.FromSeconds(15)
                }
            };
            await client.Agent.ServiceRegister(registration);

            await client.Agent.WarnTTL("service:foo", "test");

            var checks = await client.Agent.Checks();
            Assert.True(checks.Response.ContainsKey("service:foo"));

            Assert.Equal(CheckStatus.Warning, checks.Response["service:foo"].Status);

            await client.Agent.ServiceDeregister("foo");
        }
Beispiel #26
0
 private bool RegisterService(string name)
 {
     MyLogger.Trace("Entering " + MethodBase.GetCurrentMethod().Name);
     try
     {
         AgentServiceRegistration svcreg = new AgentServiceRegistration
         {
             Name = name
         };
         ConsulClient.Agent.ServiceRegister(svcreg);
         MyLogger.Debug("{0} registered in Consul Services", name);
         return true;
     }
     catch (Exception ex)
     {
         MyLogger.Error("Error in registring {0} in Consul Services: {1}", name, ex.Message);
         MyLogger.Debug(ex);
         return false;
     }
 }
 bool CreateConsulClient()
 {
     ConsulClient = new Client();
     //Deregister any leftover service
     ConsulClient.Agent.ServiceDeregister("AmazingService").Wait(5000);
     AgentServiceRegistration svcreg = new AgentServiceRegistration
     {
         Name = "AmazingService",
         Port = ListenPort,
         Address = ListenAddress,
         //,
         //        Tags = new[] { "consultest", "owintest" },
         Check = new AgentServiceCheck
         {
             TTL = TimeSpan.FromSeconds(5)
         }
     };
     //if (_consulClient.Agent.ServiceRegister(svcreg).Wait(5000)) _semaphore = _consulClient.Semaphore("AmazingService/lock", 1);
     return ConsulClient.Agent.ServiceRegister(svcreg).Wait(5000);
 }
Beispiel #28
0
        public static IApplicationBuilder UseConsul(this IApplicationBuilder app, string host = null,
                                                    string port = null)
        {
            //获取consul客户端实例
            var consulClient = app.ApplicationServices.GetRequiredService <IConsulClient>();
            var logger       = app.ApplicationServices.GetRequiredService <ILoggerFactory>().CreateLogger("AppExtensions");
            var lifetime     = app.ApplicationServices.GetRequiredService <IHostApplicationLifetime>();

            if (!(app.Properties["server.Features"] is FeatureCollection features))
            {
                return(app);
            }

            //var addresses = features.Get<IServerAddressesFeature>();
            //var address = addresses.Addresses.FirstOrDefault();
            //if (address == null)
            //{
            //    return app;
            //}

            var address = host + ":" + port;

            if (string.IsNullOrWhiteSpace(host) || string.IsNullOrWhiteSpace(port))
            {
                Console.WriteLine($"host或者port为空!");
                return(app);
            }

            Console.WriteLine($"address={address}");
            var uri = new Uri(address);

            Console.WriteLine($"host={uri.Host},port={uri.Port}");

            var registration = new AgentServiceRegistration()
            {
                ID      = $"Service-{uri.Port}",
                Name    = "WebApi",
                Address = $"{uri.Host}",
                Port    = uri.Port,
                Check   = new AgentServiceCheck()
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), //服务启动多久后注册
                    Interval = TimeSpan.FromSeconds(10),                      //健康检查时间间隔
                    HTTP     = $"{address}/HealthCheck",                      //健康检查地址
                    Timeout  = TimeSpan.FromSeconds(5)                        //超时时间
                }
            };

            logger.LogInformation("Registering with Consul");
            logger.LogInformation($"Consul RegistrationID:{registration.ID}");
            //注销
            consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true);
            //注册
            consulClient.Agent.ServiceRegister(registration).ConfigureAwait(true);
            //应用程序关闭时候
            lifetime.ApplicationStopping.Register(() =>
            {
                //正在注销
                logger.LogInformation("Unregistering from Consul");
                consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true);
            });
            //每个服务都需要提供一个用于健康检查的接口,该接口不具备业务功能。服务注册时把这个接口的地址也告诉注册中心,注册中心会定时调用这个接口来检测服务是否正常,如果不正常,则将它移除,这样就保证了服务的可用性。
            app.Map("/HealthCheck", s => { s.Run(async context => { await context.Response.WriteAsync("ok"); }); });
            return(app);
        }
Beispiel #29
0
        public static void RegisterToConsul(this IApplicationBuilder app, IConfiguration configuration, IApplicationLifetime lifetime)
        {
            lifetime.ApplicationStarted.Register(() =>
            {
                string serviceName              = configuration.GetValue <string>("consulConfig:serviceName");
                string serviceIP                = configuration.GetValue <string>("consulConfig:serviceIP");
                string consulClientUrl          = configuration.GetValue <string>("consulConfig:consulClientUrl");
                string healthCheckRelativeUrl   = configuration.GetValue <string>("consulConfig:healthCheckRelativeUrl");
                int healthCheckIntervalInSecond = configuration.GetValue <int>("consulConfig:healthCheckIntervalInSecond");
                ICollection <string> listenUrls = app.ServerFeatures.Get <IServerAddressesFeature>().Addresses;


                if (string.IsNullOrWhiteSpace(serviceName))
                {
                    throw new Exception("Please use --serviceName=yourServiceName to set serviceName");
                }
                if (string.IsNullOrEmpty(consulClientUrl))
                {
                    consulClientUrl = "http://127.0.0.1:8500";
                }
                if (string.IsNullOrWhiteSpace(healthCheckRelativeUrl))
                {
                    healthCheckRelativeUrl = "health";
                }
                healthCheckRelativeUrl = healthCheckRelativeUrl.TrimStart('/');
                if (healthCheckIntervalInSecond <= 0)
                {
                    healthCheckIntervalInSecond = 1;
                }


                string protocol;
                int servicePort = 0;
                if (!TryGetServiceUrl(listenUrls, out protocol, ref serviceIP, out servicePort, out var errorMsg))
                {
                    throw new Exception(errorMsg);
                }

                var consulClient = new ConsulClient(ConsulClientConfiguration => ConsulClientConfiguration.Address = new Uri(consulClientUrl));

                var httpCheck = new AgentServiceCheck()
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10),//服务启动多久后注册
                    Interval = TimeSpan.FromSeconds(healthCheckIntervalInSecond),
                    HTTP     = $"{protocol}://{serviceIP}:{servicePort}/{healthCheckRelativeUrl}",
                    Timeout  = TimeSpan.FromSeconds(2)
                };

                // 生成注册请求
                var registration = new AgentServiceRegistration()
                {
                    Checks  = new[] { httpCheck },
                    ID      = Guid.NewGuid().ToString(),
                    Name    = serviceName,
                    Address = serviceIP,
                    Port    = servicePort,
                    Meta    = new Dictionary <string, string>()
                    {
                        ["Protocol"] = protocol
                    },
                    Tags = new[] { $"{protocol}" }
                };
                consulClient.Agent.ServiceRegister(registration).Wait();

                //服务停止时, 主动发出注销
                lifetime.ApplicationStopping.Register(() =>
                {
                    try
                    {
                        consulClient.Agent.ServiceDeregister(registration.ID).Wait();
                    }
                    catch
                    { }
                });
            });
        }
Beispiel #30
0
        //Returns unique service ID used for removing the service from registry.
        public static string UseConsul(this IApplicationBuilder app)
        {
            using (var scope = app.ApplicationServices.CreateScope())
            {
                var consulOptions = scope.ServiceProvider.GetService <IOptions <ConsulOptions> >();
                var fabioOptions  = scope.ServiceProvider.GetService <IOptions <FabioOptions> >();
                var enabled       = consulOptions.Value.Enabled;
                var consulEnabled = Environment.GetEnvironmentVariable("CONSUL_ENABLED")?.ToLowerInvariant();
                if (!string.IsNullOrWhiteSpace(consulEnabled))
                {
                    enabled = consulEnabled == "true" || consulEnabled == "1";
                }

                if (!enabled)
                {
                    return(string.Empty);
                }


                var address = consulOptions.Value.Address;
                if (string.IsNullOrWhiteSpace(address))
                {
                    throw new ArgumentException("Consul address can not be empty.",
                                                nameof(consulOptions.Value.PingEndpoint));
                }
                //https://cecilphillip.com/using-consul-for-service-discovery-with-asp-net-core/
                // Retrieve Consul client from DI
                var uniqueId    = scope.ServiceProvider.GetService <IServiceId>().Id;
                var client      = scope.ServiceProvider.GetService <IConsulClient>();
                var serviceName = consulOptions.Value.Service;
                //create unique serviceId per service instance create, init standalone service after creation separately.
                //use when we have multiple instance of a particular microservice and because each microservice has same name
                //we need distinguish between services so for this case and we use serviceId
                var serviceId           = $"{serviceName}:{uniqueId}";
                var port                = consulOptions.Value.Port;
                var pingEndpoint        = consulOptions.Value.PingEndpoint;
                var pingInterval        = consulOptions.Value.PingInterval <= 0 ? 5 : consulOptions.Value.PingInterval;
                var removeAfterInterval =
                    consulOptions.Value.RemoveAfterInterval <= 0 ? 10 : consulOptions.Value.RemoveAfterInterval;
                // Register service with consul
                var registration = new AgentServiceRegistration
                {
                    Name    = serviceName, //name use for group name a specific service
                    ID      = serviceId,   //unique name of each instance of a service in a group
                    Address = address,
                    Port    = port,
                    //setup fabio tags as SSSD on consul and fabio create a routing table
                    Tags = fabioOptions.Value.Enabled ? GetFabioTags(serviceName, fabioOptions.Value.Service) : null
                };
                //https://cecilphillip.com/using-consul-for-health-checks-with-asp-net-core/
                //PingEnabled for checking Health
                if (consulOptions.Value.PingEnabled || fabioOptions.Value.Enabled)
                {
                    var scheme = address.StartsWith("http", StringComparison.InvariantCultureIgnoreCase)
                        ? string.Empty
                        : "http://";
                    var check = new AgentServiceCheck
                    {
                        Interval = TimeSpan.FromSeconds(pingInterval),
                        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(removeAfterInterval),
                        HTTP = $"{scheme}{address}{(port > 0 ? $":{port}" : string.Empty)}/{pingEndpoint}"
                    };
                    registration.Checks = new[] { check };
                }

                client.Agent.ServiceRegister(registration);

                return(serviceId);
            }
        }
Beispiel #31
0
        public void Agent_ServiceMaintenance()
        {
            var c = ClientTest.MakeClient();

            var serviceReg = new AgentServiceRegistration()
            {
                Name = "redis"
            };
            c.Agent.ServiceRegister(serviceReg);

            c.Agent.EnableServiceMaintenance("redis", "broken");

            var checks = c.Agent.Checks();
            var found = false;
            foreach (var check in checks.Response)
            {
                if (check.Value.CheckID.Contains("maintenance"))
                {
                    found = true;
                    Assert.AreEqual(check.Value.Status, CheckStatus.Critical);
                    Assert.AreEqual(check.Value.Notes, "broken");
                }
            }
            Assert.IsTrue(found);

            c.Agent.DisableServiceMaintenance("redis");

            checks = c.Agent.Checks();
            foreach (var check in checks.Response)
            {
                Assert.IsFalse(check.Value.CheckID.Contains("maintenance"));
            }

            c.Agent.ServiceDeregister("redis");
        }
        public static IApplicationBuilder RegisterWithConsul(this IApplicationBuilder app)
        {
            var consulClient = app.ApplicationServices
                               .GetRequiredService <IConsulClient>();
            var configuration = app.ApplicationServices
                                .GetRequiredService <IConfiguration>();
            var lifetime = app.ApplicationServices
                           .GetRequiredService <IApplicationLifetime>();

            // Get server URI and IP address
            var features  = app.Properties["server.Features"] as FeatureCollection;
            var addresses = features.Get <IServerAddressesFeature>();
            var address   = addresses.Addresses.First();
            var uri       = new Uri(address);
            var ip        = Dns.GetHostEntry(uri.Host).AddressList.FirstOrDefault(x => x.AddressFamily == AddressFamily.InterNetwork);

            // Get configured service name and id, and update id with a random number for replica handling
            var random      = new Random();
            var serviceId   = configuration["consulConfig:serviceID"] + $"_{random.Next().ToString()}";
            var serviceName = configuration["consulConfig:serviceName"];
            var serviceTags = configuration.GetSection("consulConfig:serviceTags").Get <List <string> >().ToArray();

            // AgentCheck - Possible health check options:
            //     - http://michaco.net/blog/ServiceDiscoveryAndHealthChecksInAspNetCoreWithConsul
            var tcpCheck = new AgentServiceCheck()
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                Interval = TimeSpan.FromSeconds(2),
                TCP      = $"{ip}:{uri.Port}"
            };

            var httpCheck = new AgentServiceCheck
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                Interval = TimeSpan.FromSeconds(2),
                HTTP     = $"{uri.Scheme}://{ip}:{uri.Port}/status"
            };

            // Register service with consul
            var registration = new AgentServiceRegistration
            {
                ID      = $"{serviceId}-{uri.Port}",
                Name    = serviceName,
                Address = $"{ip}",
                Port    = uri.Port,
                Tags    = serviceTags,
                Checks  = new[] { tcpCheck, httpCheck }
            };

            Console.WriteLine("Registering with Consul");
            Console.WriteLine($"IP: {ip}");
            consulClient.Agent.ServiceDeregister(registration.ID).Wait();
            consulClient.Agent.ServiceRegister(registration).Wait();

            // Enable deregistration of service from consul during clean shutdown
            lifetime.ApplicationStopping.Register(() => {
                Console.WriteLine("Deregistering from Consul");
                consulClient.Agent.ServiceDeregister(registration.ID).Wait();
            });

            return(app);
        }
Beispiel #33
0
        public void Agent_Services_MultipleChecks()
        {
            var c = ClientTest.MakeClient();
            var reg = new AgentServiceRegistration()
            {
                Name = "foo",
                Tags = new[] { "bar", "baz" },
                Port = 8000,
                Checks = new[]
                {
                    new AgentServiceCheck
                    {
                        TTL = TimeSpan.FromSeconds(15)
                    },
                    new AgentServiceCheck
                    {
                        TTL = TimeSpan.FromSeconds(15)
                    }
                }
            };
            c.Agent.ServiceRegister(reg);

            var services = c.Agent.Services();
            Assert.IsTrue(services.Response.ContainsKey("foo"));

            var checks = c.Agent.Checks();
            Assert.IsTrue(checks.Response.ContainsKey("service:foo:1"));
            Assert.IsTrue(checks.Response.ContainsKey("service:foo:2"));

            c.Agent.ServiceDeregister("foo");
        }
Beispiel #34
0
        public static IApplicationBuilder UseConsul(this IApplicationBuilder app)
        {
            var applicationLifetime = app.ApplicationServices.GetService <IHostApplicationLifetime>();

            if (applicationLifetime == null)
            {
                throw new ArgumentNullException(nameof(applicationLifetime));
            }
            var consulClient = app.ApplicationServices.GetService <IConsulClient>();

            if (consulClient == null)
            {
                throw new ArgumentNullException(nameof(consulClient));
            }

            var serviceOptions = app.ApplicationServices.GetRequiredService <IOptions <ServiceDiscoveryOptions> >();

            if (serviceOptions == null)
            {
                throw new ArgumentNullException(nameof(serviceOptions));
            }

            var env = app.ApplicationServices.GetRequiredService <IHostEnvironment>();

            if (env == null)
            {
                throw new ArgumentNullException(nameof(env));
            }

            //获取服务启动地址绑定信息
            var features  = app.Properties["server.Features"] as FeatureCollection;
            var addresses = features.Get <IServerAddressesFeature>()
                            .Addresses
                            .Select(o => new Uri(o));

            //在服务启动时,向Consul 中心进行注册
            applicationLifetime.ApplicationStarted.Register(() =>
            {
                foreach (var address in addresses)
                {
                    //设置启动服务的ID
                    var serviceId = $"{serviceOptions.Value.ServiceName}_{address.Host}:{address.Port}";

                    //设置健康检查
                    var httpCheck = new AgentServiceCheck()
                    {
                        DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1), //错误时间超过1分钟,移除
                        Interval = TimeSpan.FromSeconds(3),                       //30秒检查一次
                        HTTP     = new Uri(address, "HealthCheck").OriginalString
                    };

                    var registration = new AgentServiceRegistration()
                    {
                        Checks  = new[] { httpCheck },             //配置健康检查
                        Address = address.Host,                    //启动服务的地址
                        Port    = address.Port,                    //启动服务的端口
                        ID      = serviceId,                       //服务唯一ID
                        Name    = serviceOptions.Value.ServiceName //对外服务名称
                    };
                    //向Consul 中心进行注册
                    consulClient.Agent.ServiceRegister(registration).GetAwaiter().GetResult();
                }
            });

            //在程序停止时,向Consul 中心进行注销
            applicationLifetime.ApplicationStopped.Register(() =>
            {
                foreach (var address in addresses)
                {
                    //设定服务Id(全局唯一 unique)
                    var serviceId = $"{serviceOptions.Value.ServiceName}_{address.Host}:{address.Port}";
                    consulClient.Agent.ServiceDeregister(serviceId).GetAwaiter().GetResult();
                }
            });

            return(app);
        }
Beispiel #35
0
        public static IApplicationBuilder UseConsul(this IApplicationBuilder app)
        {
            using var scope = app.ApplicationServices.CreateScope();

            var consulOptions = scope.ServiceProvider.GetRequiredService <ConsulOptions>();
            var lifetime      = scope.ServiceProvider.GetRequiredService <IHostApplicationLifetime>();
            var client        = scope.ServiceProvider.GetRequiredService <IConsulClient>();

            if (!consulOptions.Enabled)
            {
                return(app);
            }

            if (string.IsNullOrEmpty(consulOptions.Service))
            {
                throw new ConsulConfigurationException("Service deve ter um nome");
            }

            if (consulOptions.Port == 0)
            {
                throw new ConsulConfigurationException("Service deve ter uma porta");
            }

            if (string.IsNullOrEmpty(consulOptions.Address))
            {
                throw new ConsulConfigurationException("Service deve ter um Address");
            }

            var consulServiceRegistration = new AgentServiceRegistration
            {
                ID      = consulOptions.Id,
                Name    = consulOptions.Service,
                Address = consulOptions.Address,
                Port    = consulOptions.Port,
                Tags    = consulOptions.Tags,
                Meta    = consulOptions.MetaData,
            };

            if (consulOptions.PingEnabled)
            {
                var healthService = scope.ServiceProvider.GetRequiredService <HealthCheckService>();

                if (healthService != null)
                {
                    var check = new AgentCheckRegistration()
                    {
                        HTTP              = $"http://{consulOptions.Address}/health",
                        Notes             = "Checks /health/status on localhost",
                        Timeout           = TimeSpan.FromSeconds(3),
                        Interval          = TimeSpan.FromSeconds(10),
                        DockerContainerID = System.Environment.MachineName
                    };

                    consulServiceRegistration.Checks = new[] { check };
                }
                else
                {
                    throw new ConsulConfigurationException("Verifique os parametros de configuração do consul");
                }
            }
            client.Agent.ServiceRegister(consulServiceRegistration);
            lifetime.ApplicationStopping.Register(() => client.Agent.ServiceDeregister(consulServiceRegistration.ID).Wait());

            return(app);
        }
Beispiel #36
0
        public async Task Agent_EnableTagOverride()
        {
            var reg1 = new AgentServiceRegistration
            {
                Name = "foo1",
                Port = 8000,
                Address = "192.168.0.42",
                EnableTagOverride = true
            };

            var reg2 = new AgentServiceRegistration
            {
                Name = "foo2",
                Port = 8000
            };

            using (IConsulClient client = new ConsulClient())
            {
                await client.Agent.ServiceRegister(reg1);
                await client.Agent.ServiceRegister(reg2);

                var services = await client.Agent.Services();

                Assert.Contains("foo1", services.Response.Keys);
                Assert.True(services.Response["foo1"].EnableTagOverride);

                Assert.Contains("foo2", services.Response.Keys);
                Assert.False(services.Response["foo2"].EnableTagOverride);
            }
        }
Beispiel #37
0
        public static IApplicationBuilder UseConsulRegisterService(this IApplicationBuilder app)
        {
            var appLife        = app.ApplicationServices.GetRequiredService <IApplicationLifetime>() ?? throw new ArgumentException("Missing dependency", nameof(IApplicationLifetime));
            var serviceOptions = app.ApplicationServices.GetRequiredService <IOptions <ServiceDisvoveryOptions> >() ?? throw new ArgumentException("Missing dependency", nameof(IOptions <ServiceDisvoveryOptions>));
            var consul         = app.ApplicationServices.GetRequiredService <IConsulClient>() ?? throw new ArgumentException("Missing dependency", nameof(IConsulClient));
            var loggerFactory  = app.ApplicationServices.GetRequiredService <ILoggerFactory>();

            var logger = loggerFactory.CreateLogger("ServiceDiscoveryBuilder");

            if (string.IsNullOrEmpty(serviceOptions.Value.ServiceName))
            {
                throw new ArgumentException("Service Name must be configured", nameof(serviceOptions.Value.ServiceName));
            }

            IEnumerable <Uri> addresses = null;

            if (serviceOptions.Value.Endpoints != null && serviceOptions.Value.Endpoints.Length > 0)
            {
                logger.LogInformation($"Using {serviceOptions.Value.Endpoints.Length} configured endpoints for service registration.");
                addresses = serviceOptions.Value.Endpoints.Select(p => new Uri(p));
            }
            else
            {
                logger.LogInformation($"Trying to use server.Features to figure out the service endpoints for service registration.");
                var features = app.Properties["server.Features"] as FeatureCollection;
                addresses = features.Get <IServerAddressesFeature>()
                            .Addresses
                            .Select(p => new Uri(p)).ToArray();
            }

            logger.LogInformation($"Found {addresses.Count()} endpoints: {string.Join(",", addresses.Select(p => p.OriginalString))}.");

            foreach (var address in addresses)
            {
                var serviceId = $"{serviceOptions.Value.ServiceName}_{address.Host}:{address.Port}";

                logger.LogInformation($"Registering service {serviceId} for address {address}.");

                var serviceChecks = new List <AgentServiceCheck>();

                if (!string.IsNullOrEmpty(serviceOptions.Value.HealthCheckTemplate))
                {
                    var healthCheckUri = new Uri(address, serviceOptions.Value.HealthCheckTemplate).OriginalString;
                    serviceChecks.Add(new AgentServiceCheck()
                    {
                        Status = HealthStatus.Passing,
                        DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1),
                        Interval = TimeSpan.FromSeconds(5),
                        HTTP     = healthCheckUri
                    });

                    logger.LogInformation($"Adding healthcheck for service {serviceId}, checking {healthCheckUri}.");
                }

                var registration = new AgentServiceRegistration()
                {
                    Checks  = serviceChecks.ToArray(),
                    Address = address.Host,
                    ID      = serviceId,
                    Name    = serviceOptions.Value.ServiceName,
                    Port    = address.Port
                };

                consul.Agent.ServiceRegister(registration).GetAwaiter().GetResult();

                appLife.ApplicationStopping.Register(() =>
                {
                    consul.Agent.ServiceDeregister(serviceId).GetAwaiter().GetResult();
                });
            }

            return(app);
        }
Beispiel #38
0
        public async Task Agent_SetTTLStatus()
        {
            var svcID        = KVTest.GenerateTestKeyName();
            var registration = new AgentServiceRegistration
            {
                Name  = svcID,
                Check = new AgentServiceCheck
                {
                    TTL = TimeSpan.FromSeconds(15)
                }
            };
            await _client.Agent.ServiceRegister(registration);

            await _client.Agent.WarnTTL("service:" + svcID, "warning");

            var checks = await _client.Agent.Checks();

            Assert.Contains("service:" + svcID, checks.Response.Keys);
            Assert.Equal(HealthStatus.Warning, checks.Response["service:" + svcID].Status);
            Assert.Equal("warning", checks.Response["service:" + svcID].Output);

            await _client.Agent.PassTTL("service:" + svcID, "passing");

            checks = await _client.Agent.Checks();

            Assert.Contains("service:" + svcID, checks.Response.Keys);
            Assert.Equal(HealthStatus.Passing, checks.Response["service:" + svcID].Status);
            Assert.Equal("passing", checks.Response["service:" + svcID].Output);

            await _client.Agent.FailTTL("service:" + svcID, "failing");

            checks = await _client.Agent.Checks();

            Assert.Contains("service:" + svcID, checks.Response.Keys);
            Assert.Equal(HealthStatus.Critical, checks.Response["service:" + svcID].Status);
            Assert.Equal("failing", checks.Response["service:" + svcID].Output);

            await _client.Agent.UpdateTTL("service:" + svcID, svcID, TTLStatus.Pass);

            checks = await _client.Agent.Checks();

            Assert.Contains("service:" + svcID, checks.Response.Keys);
            Assert.Equal(HealthStatus.Passing, checks.Response["service:" + svcID].Status);
            Assert.Equal(svcID, checks.Response["service:" + svcID].Output);

            await _client.Agent.UpdateTTL("service:" + svcID, "foo warning", TTLStatus.Warn);

            checks = await _client.Agent.Checks();

            Assert.Contains("service:" + svcID, checks.Response.Keys);
            Assert.Equal(HealthStatus.Warning, checks.Response["service:" + svcID].Status);
            Assert.Equal("foo warning", checks.Response["service:" + svcID].Output);

            await _client.Agent.UpdateTTL("service:" + svcID, "foo failing", TTLStatus.Critical);

            checks = await _client.Agent.Checks();

            Assert.Contains("service:" + svcID, checks.Response.Keys);
            Assert.Equal(HealthStatus.Critical, checks.Response["service:" + svcID].Status);
            Assert.Equal("foo failing", checks.Response["service:" + svcID].Output);

            await _client.Agent.ServiceDeregister(svcID);
        }
Beispiel #39
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime applicationTime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();


            //在Asp.net使用httphandler和httpmodule做拦截等  在.net core中  middleware

            //app.Map("/values", mapApp =>
            //{
            //    mapApp.Use(async (context, next) =>
            //    {
            //        Console.WriteLine("1111");
            //        await context.Response.WriteAsync("Second Middleware in. \r\n");
            //        await next.Invoke();
            //        await context.Response.WriteAsync("Second Middleware out. \r\n");
            //    });
            //    mapApp.Run(async context =>
            //    {
            //        await context.Response.WriteAsync("Second. \r\n");
            //    });
            //});

            //注册服务 告诉consul我可以提供什么服务 告诉提供服务的ip等
            string ip          = Configuration["ip"];
            string port        = Configuration["port"];
            string serviceName = "MsgService";
            string serviceId   = serviceName + Guid.NewGuid();

            //tcp/ip
            using (var consulClient = new ConsulClient(consulConfig))
            //using (var consulClient = new ConsulClient(c=> { c.Address = new Uri("http://127.0.0.1:8500");c.Datacenter = "dc1"; }))
            {
                AgentServiceRegistration asr = new AgentServiceRegistration();
                asr.Address = ip;
                asr.Port    = Convert.ToInt32(port);
                asr.ID      = serviceId;
                asr.Name    = serviceName;
                asr.Check   = new AgentServiceCheck()
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                    HTTP     = $"http://{ip}:{port}/api/Health",
                    Interval = TimeSpan.FromSeconds(10),
                    Timeout  = TimeSpan.FromSeconds(5)
                };
                consulClient.Agent.ServiceRegister(asr).Wait();
            };
            applicationTime.ApplicationStopped.Register(() =>
            {
                using (var consulClient = new ConsulClient(consulConfig))
                {
                    Console.WriteLine("应用退出,开始从consul注销");
                    consulClient.Agent.ServiceDeregister(serviceId).Wait();
                }
            });
            app.UseSwagger(c => { });

            // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
            // specifying the Swagger JSON endpoint.
            app.UseSwaggerUI(c =>
            {
                //c.RoutePrefix = "swagger/ui";
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyApi v1");
            });
            app.UseMvc();

            //app.UseStaticFiles();

            // Enable middleware to serve generated Swagger as a JSON endpoint.
        }
Beispiel #40
0
        public async Task Register(IApplicationBuilder app, string name, string tag)
        {
            var serviceProvider = app.ApplicationServices;

            var logger = serviceProvider.GetRequiredService <ILogger <ConsulHelper> >();

            var configuration       = serviceProvider.GetRequiredService <IConfiguration>();
            var healthConfiguration = configuration.GetSection("Health").Get <HealthConfiguration>() ?? new HealthConfiguration();
            var proxyConfiguration  = configuration.GetSection("Proxy").Get <ProxyConfiguration>() ?? new ProxyConfiguration();

            var features  = app.Properties["server.Features"] as FeatureCollection;
            var addresses = features?.Get <IServerAddressesFeature>();
            var address   = addresses?.Addresses.FirstOrDefault();

            if (address is null)
            {
                logger.LogError("Null address while registration");
                return;
            }

            var uri = new Uri(address);

            using var client = new ConsulClient();

            var agentRegistration = new AgentServiceRegistration()
            {
                Address = $"{uri.Scheme}://{uri.Host}",
                Port    = uri.Port,
                ID      = Assembly.GetEntryAssembly()?.GetName().Name,
                Name    = name,
                Tags    = new[] { tag }
            };

            if (healthConfiguration.UseHealthCheck)
            {
                var httpRoot = string.IsNullOrWhiteSpace(proxyConfiguration.Url)
                    ? address
                    : $"{proxyConfiguration.Url}:{uri.Port}";

                agentRegistration.Check = new AgentCheckRegistration
                {
                    HTTP     = $"{httpRoot}{healthConfiguration.HealthEndpoint}",
                    Timeout  = healthConfiguration.Timeout,
                    Interval = healthConfiguration.Interval,
                    DeregisterCriticalServiceAfter = healthConfiguration.DeregisterServiceAfter
                };
            }

            try
            {
                await client.Agent.ServiceRegister(agentRegistration);

                logger.LogInformation("Service {Name} {Address} has been registered in Consul",
                                      agentRegistration.Name, address);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "Service {Name} {Address} has NOT been registered in Consul",
                                agentRegistration.Name, address);
            }
        }
        /// <summary>
        /// 使用Consul并且注册当前API服务
        /// </summary>
        /// <returns></returns>
        public static IApplicationBuilder UseConsul(this IApplicationBuilder app)
        {
            #region check consul
            if (!isUseConsulConfigCenter)
            {
            }
            if (string.IsNullOrEmpty(consulIP))
            {
                throw new Exception("配置项Consul IP为空--->Consul:IP");
            }

            if (string.IsNullOrEmpty(consulPort))
            {
                throw new Exception("配置项Consul 端口为空--->Consul:Port");
            }

            if (string.IsNullOrEmpty(serverIP))
            {
                throw new Exception("配置项服务IP为空--->Server:IP");
            }

            if (string.IsNullOrEmpty(serverPort))
            {
                throw new Exception("配置项服务端口为空--->Server:Port");
            }
            #endregion

            var lifetime = app.ApplicationServices.GetRequiredService <IHostApplicationLifetime>();
            using (var consulClient = new ConsulClient(x =>
            {
                x.Address = new Uri(consulServerUrl);
                if (!string.IsNullOrEmpty(aclToken))
                {
                    x.Token = aclToken;
                }
            }))
            {
                var config = consulClient.KV.Get(consulServiceConfigName).Result;


                var ocelotConfig    = consulClient.KV.Get("InternalConfiguration").Result;
                var ocelotConfigVal = Encoding.UTF8.GetString(ocelotConfig.Response.Value, 0, ocelotConfig.Response.Value.Length);


                if (config.StatusCode == HttpStatusCode.NotFound)
                {
                    var putPair    = new KVPair(consulServiceConfigName);
                    var putAttempt = consulClient.KV.Put(putPair).Result;
                }
                //服务名称
                var registration = new AgentServiceRegistration()
                {
                    ID      = Guid.NewGuid().ToString("N"),
                    Name    = consulServiceName,
                    Address = serverIP,
                    Port    = Convert.ToInt32(serverPort)
                };

                if (openHealth)
                {
                    registration.Check = new AgentServiceCheck()
                    {
                        //服务启动多久后注册
                        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                        //健康检查时间间隔
                        Interval = TimeSpan.FromSeconds(10),
                        //健康检查地址
                        HTTP    = $"http://{serverIP}:{serverPort}/api/health",
                        Timeout = TimeSpan.FromSeconds(5)
                    };
                }
                // 注册服务
                consulClient.Agent.ServiceRegister(registration).Wait();
                // 应用程序终止时,注销服务
                lifetime.ApplicationStopping.Register(() =>
                {
                    consulClient.Agent.ServiceDeregister(registration.ID).Wait();
                });
                return(app);
            }
        }
Beispiel #42
0
        public static void UseMicroService(this IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime, SysConfig serviceInfo)
        {
            new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build();
            string serviceId = $" {serviceInfo.Name}-{serviceInfo.LocalAddress}";
            string address   = serviceInfo.LocalAddress.Split(new char[] { ':' }, StringSplitOptions.None)[0];
            string s         = serviceInfo.LocalAddress.Split(new char[] { ':' }, StringSplitOptions.None)[1];

            if (!string.IsNullOrEmpty(serviceInfo.ServiceDiscoveryAddress))
            {
                using (ConsulClient consulClient = new ConsulClient(x =>
                {
                    x.Address = new Uri(serviceInfo.ServiceDiscoveryAddress);
                }))
                {
                    var agentServiceRegistration = new AgentServiceRegistration
                    {
                        Address = address,
                        Port    = int.Parse(s),
                        ID      = serviceId,
                        Name    = serviceInfo.Name,
                        Check   = new AgentServiceCheck
                        {
                            DeregisterCriticalServiceAfter = new TimeSpan?(TimeSpan.FromSeconds(5.0)),
                            HTTP     = "http://" + serviceInfo.LocalAddress + "/healthcheck",
                            Interval = new TimeSpan?(TimeSpan.FromSeconds(2.0)),
                            Timeout  = new TimeSpan?(TimeSpan.FromSeconds(1.0))
                        }
                    };
                    agentServiceRegistration.Tags = new string[]
                    {
                        serviceInfo.DisplayName
                    };
                    consulClient.Agent.ServiceRegister(agentServiceRegistration, default(CancellationToken)).Wait();
                }
                lifetime.ApplicationStopped.Register(() =>
                {
                    using (ConsulClient consulClient2 = new ConsulClient(x =>
                    {
                        x.Address = new Uri(serviceInfo.ServiceDiscoveryAddress);
                    }))
                    {
                        consulClient2.Agent.ServiceDeregister(serviceId, default(CancellationToken)).Wait();
                    }
                });
                app.Map("/healthcheck", delegate(IApplicationBuilder ab)
                {
                    ab.Run(async delegate(HttpContext context)
                    {
                        await context.Response.WriteAsync("ok", default(CancellationToken));
                    });
                });
            }
            //if (!env.IsProduction())
            //{
            app.UseSwagger(opt =>
            {
                opt.RouteTemplate = "{documentName}/swagger.json";
            });
            //app.UseSwagger();
            app.UseSwaggerUI(delegate(SwaggerUIOptions opt)
            {
                opt.SwaggerEndpoint("/" + serviceInfo.Name.ToLower() + "/swagger.json", serviceInfo.DisplayName);
                opt.RoutePrefix = string.Empty;//开启默认swagger/index.html路径
                opt.DocExpansion(DocExpansion.None);
            });
            //}
            app.UseAuthentication();
        }
Beispiel #43
0
        public async Task <string> RegisterServiceAsync(string name, EndPoint endpoint, CancellationToken token = default(CancellationToken))
        {
            if (endpoint is IPEndPoint node)
            {
                var serviceId = string.Format("{0}-{1}-{2}", name, node.Address.ToString(), node.Port);
                var checkId   = string.Format("{0}-{1}", node.Address.ToString(), node.Port);

                var acr = new AgentCheckRegistration
                {
                    TCP      = node.ToString(),
                    Name     = checkId,
                    ID       = checkId,
                    Interval = TimeSpan.FromSeconds(5),
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10)
                };

                var asr = new AgentServiceRegistration
                {
                    Address = node.Address.ToString(),
                    ID      = serviceId,
                    Name    = name,
                    Port    = node.Port,
                    Check   = acr
                };

                var res = await _client.Agent.ServiceRegister(asr, token).ConfigureAwait(false);

                if (res.StatusCode != HttpStatusCode.OK)
                {
                    throw new ApplicationException($"Failed to register service {name} on endpoint {node}");
                }
                return(serviceId);
            }

            if (endpoint is DnsEndPoint dns)
            {
                var serviceId = string.Format("{0}-{1}-{2}", name, dns.Host, dns.Port);
                var checkId   = string.Format("{0}-{1}", dns.Host, dns.Port);

                var acr = new AgentCheckRegistration
                {
                    TCP      = dns.ToString(),
                    Name     = checkId,
                    ID       = checkId,
                    Interval = TimeSpan.FromSeconds(5),
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10),
                };

                var asr = new AgentServiceRegistration
                {
                    Address = dns.Host,
                    Port    = dns.Port,
                    ID      = serviceId,
                    Name    = name,
                    Check   = acr
                };

                var res = await _client.Agent.ServiceRegister(asr, token).ConfigureAwait(false);

                if (res.StatusCode != HttpStatusCode.OK)
                {
                    throw new ApplicationException($"Failed to register service {name} on endpoint {dns}");
                }
                return(serviceId);
            }

            throw new ArgumentException("The type of endpoint must be one of IPEndPoint or DnsEndPoint", nameof(endpoint));
        }
        public static IApplicationBuilder UseConsul(this IApplicationBuilder app)
        {
            var configuration = app.ApplicationServices.GetRequiredService <IConfiguration>();
            var serviceName   = configuration.GetSection("ServiceName").Value;

            var consulClient = app.ApplicationServices.GetRequiredService <IConsulClient>();
            var logger       = app.ApplicationServices.GetRequiredService <ILoggerFactory>();
            var lifeTime     = app.ApplicationServices.GetRequiredService <IApplicationLifetime>();

            if (!(app.Properties["server.Features"] is FeatureCollection features))
            {
                return(app);
            }

            var addresses = features.Get <IServerAddressesFeature>();
            var address   = addresses.Addresses.First();

            // foreach (var item in addresses.Addresses)
            // {
            //     Console.WriteLine($"inside loop - address = {item}");
            // }

            Console.WriteLine($"address = {address}");

            // var uri = new Uri(address);

            // Console.WriteLine($"Host: {uri.Host}");

            //get host name and IP
            var hostName = Dns.GetHostName(); // get container id
            var ip       = Dns.GetHostEntry(hostName).AddressList.FirstOrDefault(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);

            Console.WriteLine($"Host Name: {hostName}, IP Address: {ip}");

            // to add this service with Fabio Load balancer add httpcheck and tags in registration
            var httpcheck = new AgentServiceCheck()
            {
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                Interval = TimeSpan.FromSeconds(10),
                HTTP     = $"http://{ip}:{80}/Health/IsAlive",
                Timeout  = TimeSpan.FromSeconds(5)
            };
            // register service with Consul
            var registration = new AgentServiceRegistration()
            {
                /*
                 * ID = $"{serviceName}-{uri.Port}",
                 * Name = serviceName,
                 * Address = $"{uri.Host}",
                 * Port = uri.Port
                 */


                ID      = $"{serviceName}-{Guid.NewGuid().ToString()}",
                Name    = serviceName,
                Address = $"{ip}", // $"{hostName}",
                Port    = 80,
                // this is for fabio LB
                Tags   = new[] { $"urlprefix-/" }, // end with slash (/) to catch all route
                Checks = new[] { httpcheck }
            };

            //logger.LogInformation("Registering with Consul");

            consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true);
            consulClient.Agent.ServiceRegister(registration).ConfigureAwait(true);

            lifeTime.ApplicationStopped.Register(() =>
            {
                //logger.LogInformation("Unregistering from Consul");
                consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true);
            });

            return(app);
        }
Beispiel #45
0
        public static IApplicationBuilder UseConsul(this IApplicationBuilder app)
        {
            // 获取服务配置项
            var serviceOptions = app.ApplicationServices.GetRequiredService <IOptions <ConsulServiceOptions> >().Value;

            // 服务ID必须保证唯一
            serviceOptions.ServiceId = Guid.NewGuid().ToString();

            //consul对象
            var consulClient = new ConsulClient(consulConfig => { consulConfig.Address = new Uri(serviceOptions.ConsulAddress); });


            // 使用参数配置服务注册地址
            var config  = app.ApplicationServices.GetRequiredService <IConfiguration>();
            var address = "";//config["urls"];

            if (string.IsNullOrEmpty(address))
            {
                // 获取当前服务地址和端口
                var features = app.Properties["server.Features"] as FeatureCollection;
                address = features?.Get <IServerAddressesFeature>().Addresses.FirstOrDefault();
            }
            Console.WriteLine("--------------address:" + address);
            var uri = new Uri(address);

            var readom = new Random();
            // 节点服务注册对象
            var registration = new AgentServiceRegistration()
            {
                ID      = serviceOptions.ServiceId,
                Name    = serviceOptions.ServiceName,// 服务名
                Address = uri.Host,

                Port = uri.Port, // 服务端口
                Tags = new string[] { uri.Port.ToString() },
                Meta = new Dictionary <string, string>()
                {
                    { serviceOptions.ServiceName, serviceOptions.ServiceId },
                    { "Weight", readom.Next(10).ToString() }
                },

                Check = new AgentServiceCheck
                {
                    // 注册超时
                    Timeout = TimeSpan.FromSeconds(5),
                    // 服务停止多久后注销服务
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                    // 健康检查地址
                    HTTP = $"{uri.Scheme}://{uri.Host}:{uri.Port}{serviceOptions.HealthCheck}",
                    // 健康检查时间间隔
                    Interval = TimeSpan.FromSeconds(10),
                }
            };

            // 注册服务
            consulClient.Agent.ServiceRegister(registration).Wait();

            // 获取主机生命周期管理接口
            var lifetime = app.ApplicationServices.GetRequiredService <IHostApplicationLifetime>();

            // 应用程序终止时,注销服务
            lifetime.ApplicationStopping.Register(() =>
            {
                consulClient.Agent.ServiceDeregister(serviceOptions.ServiceId).Wait();
            });

            return(app);
        }
        public async Task Agent_SetTTLStatus()
        {
            var client       = new ConsulClient();
            var registration = new AgentServiceRegistration()
            {
                Name  = "foo",
                Check = new AgentServiceCheck
                {
                    TTL = TimeSpan.FromSeconds(15)
                }
            };
            await client.Agent.ServiceRegister(registration);

            await client.Agent.WarnTTL("service:foo", "warning");

            var checks = await client.Agent.Checks();

            Assert.Contains("service:foo", checks.Response.Keys);
            Assert.Equal(CheckStatus.Warning, checks.Response["service:foo"].Status);
            Assert.Equal("warning", checks.Response["service:foo"].Output);

            await client.Agent.PassTTL("service:foo", "passing");

            checks = await client.Agent.Checks();

            Assert.Contains("service:foo", checks.Response.Keys);
            Assert.Equal(CheckStatus.Passing, checks.Response["service:foo"].Status);
            Assert.Equal("passing", checks.Response["service:foo"].Output);

            await client.Agent.FailTTL("service:foo", "failing");

            checks = await client.Agent.Checks();

            Assert.Contains("service:foo", checks.Response.Keys);
            Assert.Equal(CheckStatus.Critical, checks.Response["service:foo"].Status);
            Assert.Equal("failing", checks.Response["service:foo"].Output);

            await client.Agent.UpdateTTL("service:foo", "foo", TTLStatus.Pass);

            checks = await client.Agent.Checks();

            Assert.Contains("service:foo", checks.Response.Keys);
            Assert.Equal(CheckStatus.Passing, checks.Response["service:foo"].Status);
            Assert.Equal("foo", checks.Response["service:foo"].Output);

            await client.Agent.UpdateTTL("service:foo", "foo warning", TTLStatus.Warn);

            checks = await client.Agent.Checks();

            Assert.Contains("service:foo", checks.Response.Keys);
            Assert.Equal(CheckStatus.Warning, checks.Response["service:foo"].Status);
            Assert.Equal("foo warning", checks.Response["service:foo"].Output);

            await client.Agent.UpdateTTL("service:foo", "foo failing", TTLStatus.Critical);

            checks = await client.Agent.Checks();

            Assert.Contains("service:foo", checks.Response.Keys);
            Assert.Equal(CheckStatus.Critical, checks.Response["service:foo"].Status);
            Assert.Equal("foo failing", checks.Response["service:foo"].Output);

            await client.Agent.ServiceDeregister("foo");
        }
Beispiel #47
0
        //Returns unique service ID used for removing the service from registry.
        public static string UseConsul(this IApplicationBuilder app)
        {
            using (var scope = app.ApplicationServices.CreateScope())
            {
                var consulOptions = scope.ServiceProvider.GetService <IOptions <ConsulOptions> >();
                var fabioOptions  = scope.ServiceProvider.GetService <IOptions <FabioOptions> >();
                var enabled       = consulOptions.Value.Enabled;
                var consulEnabled = Environment.GetEnvironmentVariable("CONSUL_ENABLED")?.ToLowerInvariant();
                if (!string.IsNullOrWhiteSpace(consulEnabled))
                {
                    enabled = consulEnabled == "true" || consulEnabled == "1";
                }

                if (!enabled)
                {
                    return(string.Empty);
                }


                var address = consulOptions.Value.Address;
                if (string.IsNullOrWhiteSpace(address))
                {
                    throw new ArgumentException("Consul address can not be empty.",
                                                nameof(consulOptions.Value.PingEndpoint));
                }

                var uniqueId            = scope.ServiceProvider.GetService <IServiceId>().Id;
                var client              = scope.ServiceProvider.GetService <IConsulClient>();
                var serviceName         = consulOptions.Value.Service;
                var serviceId           = $"{serviceName}:{uniqueId}";
                var port                = consulOptions.Value.Port;
                var pingEndpoint        = consulOptions.Value.PingEndpoint;
                var pingInterval        = consulOptions.Value.PingInterval <= 0 ? 5 : consulOptions.Value.PingInterval;
                var removeAfterInterval =
                    consulOptions.Value.RemoveAfterInterval <= 0 ? 10 : consulOptions.Value.RemoveAfterInterval;
                var registration = new AgentServiceRegistration
                {
                    Name    = serviceName,
                    ID      = serviceId,
                    Address = address,
                    Port    = port,
                    Tags    = fabioOptions.Value.Enabled ? GetFabioTags(serviceName, fabioOptions.Value.Service) : null
                };
                if (consulOptions.Value.PingEnabled || fabioOptions.Value.Enabled)
                {
                    var scheme = address.StartsWith("http", StringComparison.InvariantCultureIgnoreCase)
                        ? string.Empty
                        : "http://";
                    var check = new AgentServiceCheck
                    {
                        Interval = TimeSpan.FromSeconds(pingInterval),
                        DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(removeAfterInterval),
                        HTTP = $"{scheme}{address}{(port > 0 ? $":{port}" : string.Empty)}/{pingEndpoint}"
                    };
                    registration.Checks = new[] { check };
                }

                client.Agent.ServiceRegister(registration);

                return(serviceId);
            }
        }
Beispiel #48
0
        public async Task Agent_Checks_Docker()
        {
            using (var client = new ConsulClient())
            {
                var serviceReg = new AgentServiceRegistration()
                {
                    Name = "redis"
                };
                await client.Agent.ServiceRegister(serviceReg);

                var reg = new AgentCheckRegistration()
                {
                    Name = "redischeck",
                    ServiceID = "redis",
                    DockerContainerID = "f972c95ebf0e",
                    Script = "/bin/true",
                    Shell = "/bin/bash",
                    Interval = TimeSpan.FromSeconds(10)
                };
                await client.Agent.CheckRegister(reg);

                var checks = await client.Agent.Checks();
                Assert.True(checks.Response.ContainsKey("redischeck"));
                Assert.Equal("redis", checks.Response["redischeck"].ServiceID);

                await client.Agent.CheckDeregister("redischeck");
                await client.Agent.ServiceDeregister("redis");
            }
        }
Beispiel #49
0
        public async Task Agent_ServiceAddress()
        {
            var client = new ConsulClient();
            var registration1 = new AgentServiceRegistration()
            {
                Name = "foo1",
                Port = 8000,
                Address = "192.168.0.42"
            };
            var registration2 = new AgentServiceRegistration()
            {
                Name = "foo2",
                Port = 8000
            };

            await client.Agent.ServiceRegister(registration1);
            await client.Agent.ServiceRegister(registration2);

            var services = await client.Agent.Services();
            Assert.True(services.Response.ContainsKey("foo1"));
            Assert.True(services.Response.ContainsKey("foo2"));
            Assert.Equal("192.168.0.42", services.Response["foo1"].Address);
            Assert.True(string.IsNullOrEmpty(services.Response["foo2"].Address));

            await client.Agent.ServiceDeregister("foo1");
            await client.Agent.ServiceDeregister("foo2");
        }
        public static IApplicationBuilder UseConsulRegisterService(this IApplicationBuilder app, IHostingEnvironment env)
        {
            var loggerFactory           = app.ApplicationServices.GetService <ILoggerFactory>();
            var lifetime                = app.ApplicationServices.GetService <IApplicationLifetime>();
            var consul                  = app.ApplicationServices.GetRequiredService <IConsulClient>();
            var serviceDiscoveryOptions = app.ApplicationServices.GetService <IOptions <ServiceDiscoveryOptions> >().Value;

            var logger = loggerFactory.CreateLogger("ServiceDiscoveryBuilder");

            if (string.IsNullOrWhiteSpace(serviceDiscoveryOptions.ServiceName))
            {
                throw new ArgumentException("Service Name must be configured", nameof(serviceDiscoveryOptions.ServiceName));
            }

            IEnumerable <Uri> addresses = null;

            if (serviceDiscoveryOptions.Endpoints != null && serviceDiscoveryOptions.Endpoints.Length > 0)
            {
                logger.LogInformation($"Using {serviceDiscoveryOptions.Endpoints.Length} configured endpoints for service registration.");
                addresses = serviceDiscoveryOptions.Endpoints.Select(p => new Uri(p));
            }
            else
            {
                logger.LogInformation($"Trying to use server.Features to figure out the service endpoints for service registration.");
                var features = app.Properties["server.Features"] as FeatureCollection;//server.Features 只有在使用 kestrel托管服务时,才可用
                addresses = features.Get <IServerAddressesFeature>()
                            .Addresses.Select(p => new Uri(p));
            }

            logger.LogInformation($"Found {addresses.Count()} endpoints:{string.Join(",", addresses.Select(p => p.OriginalString))}.");
            foreach (var address in addresses)
            {
                var serviceId = $"{serviceDiscoveryOptions.ServiceName}_{address.Host}:{address.Port}";

                logger.LogInformation($"Registering service {serviceId} for address {address}.");

                var serviceChecks = new List <AgentServiceCheck>();
                //强制必须配置HealthCheckTemplate,否则不向Consul注册服务
                if (!string.IsNullOrWhiteSpace(serviceDiscoveryOptions.HealthCheckTemplate))
                {
                    var healthCheckUri = new Uri(address, serviceDiscoveryOptions.HealthCheckTemplate).OriginalString;
                    var serviceCheck   = new AgentServiceCheck()
                    {
                        DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1),
                        Interval = TimeSpan.FromSeconds(30),
                        HTTP     = healthCheckUri
                    };
                    if (env.IsDevelopment())
                    {
                        serviceCheck.DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(30);
                        serviceCheck.Interval = TimeSpan.FromSeconds(30);
                    }

                    serviceChecks.Add(serviceCheck);
                    logger.LogInformation($"Adding healthcheck for service {serviceId},checking {healthCheckUri}");


                    var registration = new AgentServiceRegistration()
                    {
                        Checks  = serviceChecks.ToArray(),
                        Address = address.Host,
                        ID      = serviceId,
                        Name    = serviceDiscoveryOptions.ServiceName,
                        Port    = address.Port
                    };

                    consul.Agent.ServiceRegister(registration).GetAwaiter().GetResult();
                    lifetime.ApplicationStopping.Register(() =>
                    {
                        consul.Agent.ServiceDeregister(registration.ID).GetAwaiter().GetResult();
                    });
                }
            }

            return(app);
        }
Beispiel #51
0
        public async Task Agent_Checks_ServiceBound()
        {
            var client = new ConsulClient();

            var serviceReg = new AgentServiceRegistration()
            {
                Name = "redis"
            };
            await client.Agent.ServiceRegister(serviceReg);

            var reg = new AgentCheckRegistration()
            {
                Name = "redischeck",
                ServiceID = "redis",
                TTL = TimeSpan.FromSeconds(15)
            };
            await client.Agent.CheckRegister(reg);

            var checks = await client.Agent.Checks();
            Assert.True(checks.Response.ContainsKey("redischeck"));
            Assert.Equal("redis", checks.Response["redischeck"].ServiceID);

            await client.Agent.CheckDeregister("redischeck");
            await client.Agent.ServiceDeregister("redis");
        }
Beispiel #52
0
        public async Task StartAsync(CancellationToken cancellationToken)
        {
            if (!_consulConfig.IsEnable)
            {
                return;
            }

            // Create a linked token so we can trigger cancellation outside of this token's cancellation
            _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

            var features = _server.Features;

            var address = _consulConfig.ServiceEndpoint;

            if (string.IsNullOrWhiteSpace(address))
            {
                var addresses = features.Get <IServerAddressesFeature>();

                _logger.Log(LogLevel.Information, $"Consul > Host All Address is: {string.Join(";", addresses.Addresses)}");

                address = addresses.Addresses.First();

                address = address.Replace("[::]", "127.0.0.1");
            }

            _logger.Log(LogLevel.Information, $"Consul > Config Service Endpoint is: {address}");

            var uri = new Uri(address);

            _registrationId = $"{_consulConfig.ServiceId}-{EnvHelper.MachineName}:{uri.Port}";

            var healthCheckPath = _healthCheckConfig.Endpoint.Trim().Replace("/", string.Empty);

            var registration = new AgentServiceRegistration
            {
                ID      = _registrationId,
                Name    = _consulConfig.ServiceName.Replace(" ", "_"),
                Address = uri.Host,
                Port    = uri.Port,
                Tags    = _consulConfig.Tags.ToArray(),
                Check   = new AgentServiceCheck()
                {
                    HTTP     = $"{uri.Scheme}://{uri.Host}:{uri.Port}/{healthCheckPath}",
                    Timeout  = _consulConfig.CheckTimeOut,
                    Interval = _consulConfig.CheckInternal,
                    DeregisterCriticalServiceAfter = _consulConfig.DeregisterDeadServiceAfter,
                },
                EnableTagOverride = true
            };

            _logger.Log(LogLevel.Information, "Consul > Registering...");

            try
            {
                await _consulClient.Agent.ServiceRegister(registration, cancellationToken);

                _logger.Log(LogLevel.Information, "Consul > Registered!");
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, "Consul > Register Failed!");
                _logger.Log(LogLevel.Error, $"Consul > {ex}");
            }
        }
        /// <summary>
        /// 创建Consul客户端注册并根据选项进行配置
        /// </summary>
        /// <param name="options">选项配置</param>
        /// <param name="getLocalServiceAddress">回调获取本地服务地址</param>
        /// <returns>Consul客户端</returns>
        public static ConsulClient CreateConsulClientRegister(ConsulOptions options, Func <string> getLocalServiceAddress = null)
        {
            if (options == null)
            {
                throw new ArgumentNullException("选项配置不能为null");
            }
            if (string.IsNullOrWhiteSpace(options.ConsulAddress))
            {
                throw new ArgumentNullException("Consul地址不能为空");
            }
            if (string.IsNullOrWhiteSpace(options.ServiceName))
            {
                throw new ArgumentNullException("服务名不能为空");
            }

            // 服务ID,如果有配置指定,则使用配置,否则由程序生成唯一
            options.ServiceId = options.ServiceId ?? $"{NetworkUtil.LocalIP}_{StringUtil.NewShortGuid()}";

            // 定义consul客户端对象
            var consulClient = new ConsulClient(clientConfig =>
            {
                clientConfig.Address    = new Uri(options.ConsulAddress);
                clientConfig.Datacenter = options.Datacenter;
            });

            // 获取本服务的地址,如果不为空,则直接取。否则取配置选项里的服务地址
            if (string.IsNullOrWhiteSpace(options.ServiceAddress) && getLocalServiceAddress != null)
            {
                options.ServiceAddress = NetworkUtil.FilterUrl(getLocalServiceAddress());
            }
            if (string.IsNullOrWhiteSpace(options.ServiceAddress))
            {
                throw new ArgumentNullException("服务地址不能为空");
            }

            var serviceUri = new Uri(options.ServiceAddress);

            // 定义一个代理服务注册对象
            var registration = new AgentServiceRegistration()
            {
                ID    = options.ServiceId,
                Tags  = options.Tags,
                Check = new AgentServiceCheck()                                                                                 // 定义健康检测对象
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(options.ServiceCheck.DeregisterCriticalServiceAfter), // 服务停止后多久注销服务
                    HTTP     = $"{serviceUri.Scheme}://{serviceUri.Host}:{serviceUri.Port}{options.ServiceCheck.HealthCheck}",  // 健康检测URL地址
                    Interval = TimeSpan.FromSeconds(options.ServiceCheck.Interval),                                             // 每隔多少时间检测
                    Timeout  = TimeSpan.FromSeconds(options.ServiceCheck.Timeout),                                              // 注册超时时间
                },
                Name    = options.ServiceName,
                Address = serviceUri.Host,
                Port    = serviceUri.Port,
            };

            // 将注册配置信息注册到consul里
            consulClient.Agent.ServiceRegister(registration).Wait();
            // 程序退出时需要反注册服务
            AppDomain.CurrentDomain.ProcessExit += (sender, e) =>
            {
                consulClient.Agent.ServiceDeregister(registration.ID).Wait();
            };

            return(consulClient);
        }
 internal bool RegisterSvcInConsul()
 {
     _parent.ConsulClient.Agent.ServiceDeregister(Name).Wait(5000);
     AgentServiceRegistration svcreg = new AgentServiceRegistration
     {
         Name = Name
     };
     return _parent.ConsulClient.Agent.ServiceRegister(svcreg).Wait(5000);
 }