我想在.net core 2.1中使用https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.ihostedservice?view=aspnetcore-2.1执行后台任务,并且需要在PCF中托管。当我在本地运行时,一切正常。启动启动后,将调用我的IHostedService的实现,并且可以通过https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.hosting.iapplicationlifetime.stopapplication?view=aspnetcore-2.1优雅地终止应用程序。但是当我主持PCF时,我遇到了错误
2018-11-09T18:27:35.359+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [OUT] Finished executing task!
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] Unhandled Exception: System.Net.Sockets.SocketException: Permission denied
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at System.Net.Sockets.Socket.Bind(EndPoint localEP)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransport.BindAsync()
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<>c__DisplayClass22_0`1.<<StartAsync>g__OnBind|0>d.MoveNext()
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] --- End of stack trace from previous location where exception was thrown ---
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.BindAsync(AddressBindContext context)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at Microsoft.AspNetCore.Server.Kestrel.Core.AnyIPListenOptions.BindAsync(AddressBindContext context)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String shutdownMessage)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at DlqProcessingApp.Program.Main(String[] args) in C:\GitRepos\DeadLetterQueueProcessingTask\Program.cs:line 72
2018-11-09T18:27:35.365+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [ERR] at DlqProcessingApp.Program.<Main>(String[] args)
2018-11-09T18:27:35.381+05:30 [APP/TASK/execute-dlqprcoessing-task/0] [OUT] Exit status 134
我正在如下Startup.cs中注册IHostedService
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add management endpoint services
services.AddCloudFoundryActuators(Configuration);
services.AddSingleton<IHostedService, DlqProcessingHostedService>();
My implementation looks like below
public class DlqProcessingHostedService : IHostedService
{
private readonly IApplicationLifetime _appLifetime;
private readonly ILogger<DlqProcessingHostedService> _logger;
private readonly IServiceScopeFactory _serviceScopeFactory;
public DlqProcessingHostedService(IApplicationLifetime appLifetime,
IServiceScopeFactory serviceScopeFactory,
ILogger<DlqProcessingHostedService> logger)
{
_appLifetime = appLifetime;
_logger = logger;
_serviceScopeFactory = serviceScopeFactory;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
using (var scope = _serviceScopeFactory.CreateScope())
{
var he = scope.ServiceProvider.GetRequiredService<HealthEndpoint>();
var worker = scope.ServiceProvider.GetRequiredService<IWorker>();
CheckStartupHealth(he);
await worker.ProcessDlxMessages();
}
_appLifetime.StopApplication();
}
public async Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Finished executing task!");
}
顺便说一句,如果我使用的是通用主机https://jmezach.github.io/2017/10/29/having-fun-with-the-.net-core-generic-host/而不是WebHost,则可以正常工作。因此,基本上我想知道IHostedService实现在PCF环境中是否对WebHost产生任何问题(尽管在本地运行良好)。我正在使用以下软件包,并以cflinuxfs2堆栈为目标。请让我知道我可能做错了。
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0" />
<PackageReference Include="Steeltoe.Extensions.Configuration.CloudFoundryCore" Version="2.1.1" />
<PackageReference Include="RabbitMQ.Client" Version="5.1.0" />
<PackageReference Include="Steeltoe.CloudFoundry.ConnectorCore" Version="2.1.1" />
<PackageReference Include="Steeltoe.Management.CloudFoundryCore" Version="2.1.1" />
</ItemGroup>
这是我的Program.cs
public class Program
{
public static async Task Main(string[] args)
{
//var host = new HostBuilder()
//.ConfigureAppConfiguration((hostContext, config) =>
//{
// var env = hostContext.HostingEnvironment;
// config.SetBasePath(Directory.GetCurrentDirectory());
// config.AddEnvironmentVariables();
// config.AddCommandLine(args);
// config.AddJsonFile("appsettings.json", true, false);
// config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, false);
// config.AddCloudFoundry();
//})
//.ConfigureServices((hostContext, services) =>
//{
// ConfigureServices(services, hostContext.Configuration);
//})
//.ConfigureLogging((hostContext, logBuilder) =>
//{
// logBuilder.ClearProviders();
// logBuilder.AddConfiguration(hostContext.Configuration.GetSection("Logging"));
// logBuilder.AddDynamicConsole();
// if (hostContext.HostingEnvironment.IsDevelopment())
// {
// logBuilder.AddDebug();
// }
//});
//await host.RunConsoleAsync();
BuildWebHost(args).Run();
Console.WriteLine("Finished executing task!");
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost
.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureAppConfiguration((builderContext, config) =>
{
config.AddCloudFoundry();
})
.ConfigureLogging((hostContext, logBuilder) =>
{
logBuilder.ClearProviders();
logBuilder.AddConfiguration(hostContext.Configuration.GetSection("Logging"));
logBuilder.AddDynamicConsole();
if (hostContext.HostingEnvironment.IsDevelopment())
{
logBuilder.AddDebug();
}
}).Build();