删除 Service Fabric 应用程序后,进程仍保持 运行

Processes still keep running after Service Fabric App is removed

我在删除服务结构应用程序时看到了这一点。 应用程序内部服务的旧流程仍然保持 运行.

App包含的服务类型

我在重新部署应用程序时注意到了这个问题,ASP.NET 核心服务为 "EADDRINUSE address already in use"

抛出了一个错误

是否有正确的方法来彻底删除停止服务的所有内部进程的应用程序?

流程中是否有可以捕获的取消事件?

我正在使用以下 class 将其注册为无状态服务。

/// <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);

主机进程只有在其中仍有服务副本时才会挂起。如果删除所有服务副本,则宿主进程将退出。

如果您删除了整个应用程序并且主机进程仍然 运行,这很可能意味着您的服务代码在要求关闭时没有响应。您的 RunAsync 方法未侦听其取消令牌,或者您的 ICommunicationListener 在调用 CloseAsync 时未关闭(也许您有未完成的请求需要一段时间才能完成)。

我从空的 WebApi 开始,您可以从服务结构 .NET 核心 WebApi 模板中获得一个。 继续添加功能,直到我看到服务没有正常关闭。

我发现我们正在使用 Unity 注入控制器。

由于我们不应该注入控制器,因此我更新以删除它并通过 Unity 更新了其他注入以支持内置的 IServiceCollection 注入。

进行这些更改后,我在升级时没有看到端口已在使用错误。 我确实看到旧进程仍然 运行,但没有使用任何 CPU 和内存(0.1M),然后在 10-15 分钟后消失。