Azure service fabric 服务结构无法重新配置副本

Azure service fabric 服务结构无法重新配置副本,azure-service-fabric,Azure Service Fabric,在应用程序的负载测试期间(使用动态负载报告服务),整个应用程序停止工作,因为有状态分区的一个副本发出警告 Warning System.RAP IStatefulServiceReplica.ChangeRole(S)Duration Thu, 21 Jul 2016 3:36:03 GMT Infinity 131135817636324745 false false Start Time (UTC): 2016-07-21 13:35:43.632 这发生在副本的负载平衡之后,这发生在分

在应用程序的负载测试期间(使用动态负载报告服务),整个应用程序停止工作,因为有状态分区的一个副本发出警告

Warning System.RAP IStatefulServiceReplica.ChangeRole(S)Duration Thu, 21 Jul 2016  3:36:03 GMT Infinity 131135817636324745 false false Start Time (UTC): 2016-07-21 13:35:43.632
这发生在副本的负载平衡之后,这发生在分区的第4个副本上,尽管我们只针对3个副本。因此,即使SF只是终止了它,应用程序也应该是好的(因为主应用程序和其他2个辅助应用程序都启动了)。然而,整个事情都陷入了困境。(从日志记录中,我可以看到至少有10k个事件仍然需要处理,但整个过程都停止了)

在上面的图像中,您可以看到特定副本的详细信息。此复制副本与其他辅助复制副本之间的唯一区别在于以下值:

  • 读取状态
  • 写入状态
  • 当前服务操作
  • 队列内存大小(在复制队列中)
  • 第一个序列号(在复制队列中)
  • 上次复制操作收到时间Utc
  • 上次复制操作接收时间Utc
  • 上次确认发送时间Utc
  • 我还觉得奇怪的是,复制副本状态显示:就绪,不再重新配置。正如读/写状态所示,它仍在重新配置 我正在运行最新的SDK(2.1.163,于2016年7月18日发布)。我原以为错误修正就在那里,但即使它变得更难复制,它仍然发生了。有人知道这可能是什么原因或如何修复吗

    编辑:失败分区的屏幕截图


    编辑:调试结果,基于Vaclav的回答(22-7-2016) 在收到Vaclav的响应后,我开始记录RunAsync中的所有内容,以确定问题的实际原因。那么,如果请求取消,代码的哪一部分没有退出呢。正如瓦茨拉夫指出的那样,当要求取消时,该方法并没有停止。然而,它似乎被卡住的代码部分是本机服务结构

    using(ITransaction tx = StateManager.CreateTransaction())
    {
      await queue.TryDequeueAsync(tx, _queueTimeout, cancellationToken);
      await tx.CommitAsync();
    }
    
    队列是可靠队列,超时设置为默认的4秒,cancelationtoken来自RunAsync。在每行之间添加日志之后,我们得到了以下日志模式

    //pre transaction
    using(ITransaction tx = StateManager.CreateTransaction())
    {
      //pre dequeue
      await queue.TryDequeueAsync(tx, _queueTimeout, cancellationToken);
      //dequeued
      await tx.CommitAsync();
      //committed
    }
    //post transaction
    
    在每一行,我都记录了cancelationrequest的值,并且在启动cancelationrequest时会记录一个后台任务。因此,我们得到了以下示例:

    pre transaction: False
    predequeue: False
    dequeued: False
    CancelationTokenFired: True
    
    精确位置可能会有所不同,但在CancelationTokenFired之前的最后一个日志始终是

  • 交易前
  • 请求前
  • 出列

  • 如前所述,这是在最新的SDK(18-7-2016)上完成的,该SDK据称针对类似问题进行了错误修复。这个问题也发生在旧的SDK上,在当时更为频繁。但是,即使在新版本上,每次运行时它仍然可以复制。

    此警告意味着您的服务的主副本在重新配置期间更改角色时,您的服务没有退出RunAsync(请查看上一个屏幕截图中的运行状况警告)。确保在每个可能的代码路径中都使用该取消令牌。这也适用于通信侦听器-确保它们响应CloseAsync()

    鉴于你所说的,以下是最有可能发生的情况:

  • 我们在一个新节点上构建了一个新副本(可能是为了负载平衡)。此时,在重新配置完成之前,您暂时拥有4个副本
  • 我们尝试将原色交换到这个新副本
  • 您当前的主服务器被告知更改角色,这意味着取消RunAsync并关闭通信侦听器
  • 当前主服务器未完成角色更改-RunAsync未退出或通信侦听器未关闭
  • 重新配置在等待当前主服务器完成角色更改时被卡住
  • 发出健康警告
  • 一旦重新配置完成,您的副本集大小将减少回目标值3

    我们不会杀死您的慢速复制副本,因为我们不知道您的应用程序是否正常—可能需要很长时间才能安全地处理有价值的数据—我们不知道。ServiceFabric非常偏执于安全,不会做任何可能导致您的服务丢失数据的事情


    不幸的是,Service Fabric Explorer没有显示重新配置状态,它显示的是预期的最终结果。但是,如果在PowerShell中运行Get-ServiceFabricPartition,它将显示分区的重新配置状态

    我经常看到这种情况,一段时间以来一直把头撞在砖墙上


    然而,看看最新的版本-5.1.163和2.1.163-这似乎已经解决了我的问题

    我已经对它进行了测试,确实RunAsync没有正确关闭,但是我们的计算不会花费更长的时间。SF的一部分被卡住了。有关所有信息,请参见我文章中的编辑。我希望你能帮助我。我们也能重新解释这件事。问题是,在关闭状态管理器之前,我们会等待您的RunAsync完成,因此,如果您恰好在此时调用CommitAsync,它将在尝试提交时持续旋转。在我们发布更新之前,您可以将所有RunAsync代码包装在一个任务中,并从RunAsync运行该任务,但不要在RunAsync中等待该任务。其思想是允许RunAsync在不等待代码的情况下完成。当修复可用时,我会更新这个答案。正如我在帖子中所说,我已经在那个版本上了,它变得更好了,但在最新版本上仍然是一个问题。每次测试都会发生一个错误-我没有看到那里的版本我不使用取消令牌进行任何可靠的收集操作。在不更改超时或添加取消令牌的情况下进行尝试。@Nick这是我们以前的做法,但也不起作用。另外,不管您如何称呼它:)这是在适当的集群上还是在本地主机开发集群上?我可能在本地主机开发集群上看到了类似的东西。@NickRandell