在Service Fabric中删除服务的适当方法是什么?

时间:2017-06-07 14:26:29

标签: azure azure-service-fabric

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

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

<!doctype html>
<html ng-app="customControl">
  <head>
    <script src="http://code.angularjs.org/1.2.0-rc.2/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <form name="myForm">
     <div contenteditable
          name="myWidget" ng-model="userContent"
          strip-br="true"
          required>Change me!</div>
      <span ng-show="myForm.myWidget.$error.required">Required!</span>
     <hr>
     <textarea ng-model="userContent"></textarea>
    </form>
  </body>
</html>

当我知道在任何情况下都应该删除服务时,删除服务的适当方法是什么。我想避免一个经理&#39;跟踪这些事情的服务,因为现在他们非常自足。

3 个答案:

答案 0 :(得分:1)

所以我找到的唯一解决方案如下:

之前,我使用的是不推荐使用的DeleteServiceAsync(Uri)覆盖。当我看到这个警告时(尴尬地说我有一段时间没有检查过警告)。我转换为DeleteServiceAsync(删除服务描述)重载,它具有一个名为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);

答案 1 :(得分:0)

您可以使用powershell命令删除该服务 删除 - ServiceFabricService 请看这里的文档 https://docs.microsoft.com/en-us/powershell/module/servicefabric/Remove-ServiceFabricService?view=azureservicefabricps

死锁问题可能是由于您的代码未检查取消令牌。这个想法是当你停止告诉服务结构停止服务取消令牌应该传递到你的代码。如果您编码不检查令牌,则服务结构无法正常停止服务。这是位

  //do work as described above

答案 2 :(得分:0)

这就是我要做的

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标志。