问题
I have seen that when I remove a service fabric application. The old processes for the services inside the application still keep running.
The services included in the Apps are of types
Actors
Stateless Services
ASP.NET Core
I noticed the problem when I redeployed the application and the ASP.NET Core service threw an error for "EADDRINUSE address already in use"
Is there a proper way to cleanly remove the application which stops all the internal processes for the services?
Is there any cancellation event which can be captured in the processes?
I am using the following class for Registering it as a Stateless service.
/// <summary>
/// A specialized stateless service for hosting ASP.NET Core web apps.
/// </summary>
internal sealed class WebHostingService : StatelessService, ICommunicationListener
{
private readonly string _endpointName;
private IWebHost _webHost;
public WebHostingService(StatelessServiceContext serviceContext, string endpointName)
: base(serviceContext)
{
_endpointName = endpointName;
}
#region StatelessService
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[] { new ServiceInstanceListener(_ => this) };
}
#endregion StatelessService
#region ICommunicationListener
void ICommunicationListener.Abort()
{
_webHost?.Dispose();
}
Task ICommunicationListener.CloseAsync(CancellationToken cancellationToken)
{
_webHost?.Dispose();
return Task.FromResult(true);
}
Task<string> ICommunicationListener.OpenAsync(CancellationToken cancellationToken)
{
var endpoint = FabricRuntime.GetActivationContext().GetEndpoint(_endpointName);
string serverUrl = $"{endpoint.Protocol}://{FabricRuntime.GetNodeContext().IPAddressOrFQDN}:{endpoint.Port}";
_webHost = new WebHostBuilder().UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseUrls(serverUrl)
.Build();
_webHost.Start();
return Task.FromResult(serverUrl);
}
#endregion ICommunicationListener
}
And Registering it like this
ServiceRuntime.RegisterServiceAsync("WebApiType", context => new WebHostingService(context, "ServiceEndpoint")).GetAwaiter().GetResult();
Thread.Sleep(Timeout.Infinite);
回答1:
I started out with empty WebApi, one you get from the service fabric .NET core WebApi templates. Continued to add features till I could see services not shutting down properly.
I found out that we were injecting controllers with Unity.
As we should not be injecting controller, I updated to remove that and also updated other Injections via Unity in favor of the built in IServiceCollection injections.
After these changes I do not see port already in use errors when I upgrade. I do see the old process still running though but not using any CPU and memory(0.1M) and then die out after 10-15mins.
回答2:
The host process will only hang around if there is still a service replica in it. If all service replicas are removed, the host process will exit.
If you've removed the entire application and the host processes are still running, it most likely means your service code is not responding when asked to close. Either you have a RunAsync method that isn't listening to its cancellation token, or you have an ICommunicationListener that isn't closing when CloseAsync is called (maybe you have outstanding requests that are taking a while to complete).
来源:https://stackoverflow.com/questions/43351810/processes-still-keep-running-after-service-fabric-app-is-removed