Azure 在服务结构中删除服务的适当方式是什么?

Azure 在服务结构中删除服务的适当方式是什么?,azure,azure-service-fabric,Azure,Azure Service Fabric,我有一个在服务结构中运行的应用程序。组成应用程序的服务之一是只有run方法的有状态服务。它查询其他服务,在运行时做一些记录,然后生成一个输出。成功完成工作后,它将输出保存到Blob存储器,然后删除自身。我使用它进行随需应变的弹性计算报告 如果我调用ServiceManager服务来删除服务本身,它似乎会死锁。这对我来说是有意义的,因为调用很可能在返回调用方之前等待run方法的完成(在这种情况下,调用方在run方法本身中,因此它实际上在等待自己)。我的下一种方法是基本上忽略异步删除服务的任务,如下

我有一个在服务结构中运行的应用程序。组成应用程序的服务之一是只有run方法的有状态服务。它查询其他服务,在运行时做一些记录,然后生成一个输出。成功完成工作后,它将输出保存到Blob存储器,然后删除自身。我使用它进行随需应变的弹性计算报告

如果我调用ServiceManager服务来删除服务本身,它似乎会死锁。这对我来说是有意义的,因为调用很可能在返回调用方之前等待run方法的完成(在这种情况下,调用方在run方法本身中,因此它实际上在等待自己)。我的下一种方法是基本上忽略异步删除服务的任务,如下所示:

protected override async Task RunAsync(CancellationToken can)
{

    //do work as described above

    Task ignored = Task.Factory.Run(async ()=>{
       await s_FabricClient.ServiceManager.DeleteServiceAsync(/*blah blah*/);
    }
    await Task.Delay(30000);
}

当我知道在任何情况下都应该删除服务时,删除服务的适当方式是什么。我希望避免使用跟踪这些内容的“管理器”服务,因为现在它们非常独立。

您可以使用powershell命令删除该服务 删除ServiceFabricService 请在这里查看文档

死锁问题可能是由于您的代码没有检查取消令牌。其思想是当您停止时,告诉ServiceFabric停止服务,应该将服务取消令牌传递到您的代码中。如果代码未检查令牌,则服务结构无法正常停止服务。这是一点

  //do work as described above

因此,我找到的唯一解决方案如下:

以前,我使用的是不推荐使用的DeleteServiceAsync(Uri)重写。当我看到这个警告时(不好意思说我有一段时间没有检查警告了)。我转换为DeleteServiceAsync(Delete​服务​说明)具有名为ForceDelete的属性的重载。这基本上不会给服务一个正常关闭的机会。由于服务本身正在发出请求,而且我知道此时我的服务已经完成,所以我可以放心地调用它

它可能不是每个用例的最终解决方案,但考虑到我的需求,这似乎是合理的

s_FabricClient.DeleteServiceAsync(new Uri("fabric:/myapp/myservice/instance123"));
现在是:

Uri serviceUri = new Uri("fabric:/myapp/myservice/instance123");
DeleteServiceDescription description = new DeleteServiceDescription(serviceUri)
{
 ForceDelete = true
};
s_FabricClient.DeleteServiceAsync(description);
我就是这么做的

private async Task DeleteSelf(CancellationToken cancellationToken)
{
       using (var client = new FabricClient())
       {
            await client.ServiceManager.DeleteServiceAsync(new DeleteServiceDescription(this.Context.ServiceName), TimeSpan.FromMinutes(1), cancellationToken);
       }
}
然后,在RunAsync方法的最后一行中,我调用:

await DeleteSelf(cancellationToken).ConfigureAwait(false);

ConfigureAwait(false)
将有助于解决死锁问题,因为它将基本上返回到一个新的线程同步上下文,即不尝试返回到“调用方上下文”。现在也不需要使用
ForceDelete
标志

这并没有解决问题。这些服务根据需要上下浮动,这是运行报表的新服务实例。在任何给定的时间,可能有成千上万的人在运行,我不希望(我也不能)手动创建或删除这些服务。当服务完成时,你可以使用PoBeS壳或不同的服务来使用创建服务的命令来自动创建/删除服务吗?它可以通过提醒的方式变得活跃,完成后会自动被GC'ed。考虑到您可以拥有数千个实例,参与者将产生更少的开销,因为他们共享一个服务流程。默认情况下,可靠的服务也是如此。您必须明确表示希望服务实例在其自己的进程中运行。演员不太理想,尤其是有计时器的演员。运行计时器有很多开销,特别是因为如果进程停止,我还必须运行一个提醒来“唤醒”参与者。