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"); }
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"); } }
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"); } }
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); } }
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); }
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"); }
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"); }
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); }
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"); }
/// <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); }
public ConsulServiceRegistrar(ILoggerFactory log, IConsulClient client, AgentServiceRegistration serviceRegistration) { _log = log.CreateLogger(nameof(ConsulServiceRegistrar)); _client = client; _serviceRegistration = serviceRegistration; }
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}]"); }); } }
public static void Registor(AgentServiceRegistration agentService) { AgentServices.Add(agentService); ConsulClientInstance.Agent.ServiceRegister(agentService); }
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"); }
#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); }
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"); }
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"); }
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); }
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); }
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 { } }); }); }
//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); } }
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); }
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"); }
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); }
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); }
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); } }
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); }
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); }
// 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. }
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); } }
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(); }
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); }
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); }
//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); } }
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"); } }
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); }
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"); }
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); }