我在移除服务结构应用程序时已经看到了。 应用程序内部服务的旧进程仍在继续运行。
应用程序中包含的服务属于
类型演员
无国籍服务
ASP.NET Core
我在重新部署应用程序时注意到了这个问题,并且ASP.NET Core服务因为#34; EADDRINUSE地址已经在使用而引发错误"
是否有正确的方法可以彻底删除停止服务的所有内部流程的应用程序?
是否有可以在流程中捕获的取消事件?
我使用以下类将其注册为无状态服务。
/// <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
}
并像这样注册
ServiceRuntime.RegisterServiceAsync("WebApiType", context => new WebHostingService(context, "ServiceEndpoint")).GetAwaiter().GetResult();
Thread.Sleep(Timeout.Infinite);
答案 0 :(得分:1)
我从空WebApi开始,你可以从服务结构.NET核心WebApi模板获得。 继续添加功能,直到我看到服务没有正常关闭。
我发现我们正在使用Unity注入控制器。
由于我们不应该注入控制器,我更新了删除它,并通过Unity更新了其他注入,支持内置的IServiceCollection注入。
在进行这些更改后,我在升级时看不到端口已经处于使用错误状态。 我确实看到旧的进程仍在运行,但没有使用任何CPU和内存(0.1M),然后在10-15分钟后消失。
答案 1 :(得分:0)
主机进程只有在其中仍有服务副本时才会出现。如果删除了所有服务副本,则主机进程将退出。
如果您删除了整个应用程序并且主机进程仍在运行,则很可能意味着当您要求关闭时,您的服务代码没有响应。您有一个没有侦听其取消令牌的RunAsync方法,或者您有一个ICommunicationListener在调用CloseAsync时没有关闭(可能您有未完成的请求需要一段时间才能完成)。