删除 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 应用后,进程仍继续运行的主要内容,如果未能解决你的问题,请参考以下文章

通过 ARM 模板删除 Service Fabric 服务

是否可以添加或删除 Service Fabric 有状态服务命名分区

Service Fabric 运行时未从 Actor 服务实例回收未使用的内存

Service Fabric 中的 actorevent 都有哪些限制?

Service Fabric - 如何修复失败的有状态应用程序

Service Fabric 中的 Stateless Worker 服务在同一进程中重新启动