删除 Service Fabric 应用后,进程仍继续运行

Posted

技术标签:

【中文标题】删除 Service Fabric 应用后,进程仍继续运行【英文标题】:Processes still keep running after Service Fabric App is removed 【发布时间】:2017-09-07 04:30:39 【问题描述】:

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

应用中包含的服务类型

演员

无状态服务

ASP.NET 核心

我在重新部署应用程序时注意到了这个问题,并且 ASP.NET Core 服务为“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);

【问题讨论】:

是的,它叫RunAsync。 你看到这篇关于托管 aspnet 核心的文章了吗? docs.microsoft.com/en-us/azure/service-fabric/… 如果您使用 'AspNetCoreCommunicationListener' 可能会有所帮助 @LoekD 确实查看了这篇文章。更新为使用 WebListenerCommunicationListener。但我仍然收到错误 “前缀 'http://+:8800/' 已注册。” 在升级或删除和安装时。 【参考方案1】:

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

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

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

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

【讨论】:

【参考方案2】:

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

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

【讨论】:

我没有覆盖 RunAsync,正如您在上面的问题中看到的那样。 现在我更新为使用 service-fabric-aspnetcore 包来初始化 IWebHost 并将它的管理留给包。查看 Git 存储库“AspNetCoreCommunicationListener.cs”,我也没有看到对 RunAsync 的任何处理,但我仍然看到相同的问题。现在作为一种解决方法,我使用随机端口并使用命名服务进行外部通信。 我与@viluMal 合作。我们在使用动态端口时遇到与端口冲突相关的差异升级错误。我们还通过任务管理器注意到 WebApi WebListener Stateless Service .exe 没有在合理的时间内关闭。我们正在使用您的示例和 AspNet Core VS2017 最新模板。关闭时似乎没有调用 RunAsync。除非集群与服务有某种开放式通信,否则这些服务没有未完成的请求。

以上是关于删除 Service Fabric 应用后,进程仍继续运行的主要内容,如果未能解决你的问题,请参考以下文章