Я использую микросервис ASP.NET Core под IIS 10.0 и пытаюсь зарегистрировать его в Консуле при запуске.Я добавил следующий код в Startup.ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton<IHostedService, ConsulHostedService>();
services.Configure<ConsulConfig>(Configuration.GetSection("consulConfig"));
services.AddSingleton<IConsulClient>(p => new ConsulClient(ConfigOverride));
}
private void ConfigOverride(ConsulClientConfiguration config)
{
var address = Configuration["ConsulConfig:ConsulAddress"];
config.Address = new Uri(address);
}
Это прекрасно работает при запуске в качестве отдельного проекта, но при запуске в IIS служба не регистрируется сама по себе, пока я не нажму "Обзор", По словам Сезара де ла Торре , ConsulHostedService.Startup следует вызывать во время запуска приложения, но, похоже, этого не происходит.
Учитывая тот факт, что это не кажетсяпроблема, возникающая при работе в автономном режиме, похоже, это проблема IIS, но я не могу понять, какие, в частности, настройки, которые мне нужно переключить.Единственное, что мне показалось связанным, было «Preload Enabled» в расширенных настройках сайта, но безуспешно.
Если в моем коде что-то отсутствует, вот полный класс Startup:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSingleton<IHostedService, ConsulHostedService>();
services.Configure<ConsulConfig>(Configuration.GetSection("consulConfig"));
services.AddSingleton<IConsulClient>(p => new ConsulClient(ConfigOverride));
}
private void ConfigOverride(ConsulClientConfiguration config)
{
var address = Configuration["ConsulConfig:ConsulAddress"];
config.Address = new Uri(address);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseHsts();
app.UseMvc();
}
}
И ConsulHostedService:
public class ConsulHostedService : IHostedService
{
private CancellationTokenSource _cts;
private readonly IConsulClient _consulClient;
private readonly IOptions<ConsulConfig> _consulConfig;
private readonly ILogger<ConsulHostedService> _logger;
private readonly IServer _server;
private string _registrationId;
public ConsulHostedService(IConsulClient consulClient, IOptions<ConsulConfig> consulConfig,
ILogger<ConsulHostedService> logger, IServer server)
{
_consulClient = consulClient;
_consulConfig = consulConfig;
_logger = logger;
_server = server;
}
public async Task StartAsync(CancellationToken token)
{
_cts = CancellationTokenSource.CreateLinkedTokenSource(token);
var uri = GetServerAddress();
_registrationId = $"{_consulConfig.Value.ServiceId}-{_consulConfig.Value.ServicePort}";
AgentServiceRegistration registration = MakeConsulRegistration(uri);
await Register(registration);
}
private Uri GetServerAddress()
{
var features = _server.Features;
var addresses = features.Get<IServerAddressesFeature>();
var address = addresses.Addresses.First();
return new Uri(address);
}
private AgentServiceRegistration MakeConsulRegistration(Uri uri)
{
return new AgentServiceRegistration()
{
ID = _registrationId,
Name = _consulConfig.Value.ServiceName,
Address = $"http://localhost",
Port = _consulConfig.Value.ServicePort,
Tags = _consulConfig.Value.ServiceTags,
Check = MakeConsulCheck(uri)
};
}
private AgentServiceCheck MakeConsulCheck(Uri uri)
{
return new AgentServiceCheck()
{
HTTP = $"http://localhost:{_consulConfig.Value.ServicePort}/api/meta/status",
Timeout = TimeSpan.FromSeconds(3),
Interval = TimeSpan.FromSeconds(10)
};
}
private async Task Register(AgentServiceRegistration registration)
{
_logger.LogInformation("Registering in Consul");
await _consulClient.Agent.ServiceDeregister(registration.ID, _cts.Token);
await _consulClient.Agent.ServiceRegister(registration, _cts.Token);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
_cts.Cancel();
_logger.LogInformation("Deregistering from Consul");
try
{
await _consulClient.Agent.ServiceDeregister(_registrationId, cancellationToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "Deregistration failed");
}
}
}