Service Fabric自动删除服务

时间:2018-05-21 10:13:23

标签: service-fabric-stateless azure-service-fabric

我想添加一个服务,在系统首次创建时为系统执行一些初始化操作。

我认为这将是一个无状态服务(具有集群管理员权限),当它完成时它应该自毁。我under the impression that exiting the RunAsync function允许我指出我已经完成(或处于错误状态)。然而,它仍然在应用程序的上下文中徘徊,并且当它根本没有做任何事情时,看起来像是“活跃的”。

服务是否可以自行删除?

我想也许我们可以尝试在FabricClient.ServiceManager覆盖中使用DeleteServiceAsync的{​​{1}}(使用基于服务上下文的参数),但我无法证明可能会工作,感觉有点时髦:

OnCloseAsync

有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

从RunAsync返回将结束RunAsync中的代码(指示完成),因此SF不会再次启动RunAsync(例如,如果它返回异常,则会发生)。 RunAsync完成不会导致服务被删除。如上所述,例如,服务可以通过后台工作完成,但仍然可以监听传入的消息。

关闭服务的最佳方法是调用DeleteServiceAsync。这可以由服务本身或其他服务完成,也可以从群集外部完成。服务可以自行删除,因此对于工作完成的服务,我们通常会看到等待DeleteServiceAsync作为RunAsync的最后一行,之后该方法才会退出。类似的东西:

RunAsync(CancellationToken ct)
{
    while(!workCompleted && !ct.IsCancellationRequested)
    {
        if(!DoneWithWork())
        {
            DoWork()
        }

        if(DoneWithWork())
        {
            workCompleted == true;
            await DeleteServiceAsync(...) 
        }
    }
}

目标是确保如果您的服务实际完成了工作,它会自行清理,但不会因为CancellationToken可以发出信号的其他原因而触发自己的删除,例如由于关闭而关闭一些升级或集群资源平衡。

答案 1 :(得分:1)

如前所述,从RunAsync返回仅将结束此方法,但是该服务将继续运行,因此不会被删除。

beforeunload当然是要走的路-但是它并不像调用它那样简单,因为如果您不小心,它将死锁在当前线程上(尤其是在本地开发人员集群中)。您还可能会收到一些短期运行状况警告,提示有关RunAsync需要很长时间终止和/或未达到目标副本大小。

在任何情况下-解决方案都非常简单-只需执行以下操作:

window.addEventListener("beforeunload", function (e) {
    var confirmationMessage = "If you refresh your page you will need to use the link provided by the coordinator to access again. Do you want to continue?";
    e.returnValue = confirmationMessage;
    return confirmationMessage;
});

然后,在我的RunAsync方法的最后一行中调用:

DeleteServiceAsync

private async Task DeleteSelf(CancellationToken cancellationToken) { using (var client = new FabricClient()) { await client.ServiceManager.DeleteServiceAsync(new DeleteServiceDescription(this.Context.ServiceName), TimeSpan.FromMinutes(1), cancellationToken); } } 将有助于解决死锁问题,因为它实际上将返回到新的线程同步上下文-即,不要尝试返回“调用者上下文”。