【问题标题】:What can cause ITransaction.CommitAsync calls to take a really long time (24h)?什么会导致 ITransaction.CommitAsync 调用需要很长时间(24 小时)?
【发布时间】:2016-12-08 19:26:34
【问题描述】:

我们在使用 ITransaction.CommitAsync 时遇到了一些奇怪的行为。有时,对 CommitAsync 的调用需要 24 小时才能完成。

在我们的场景中,我们每 5 分钟从硬件设备读取仪表数据,并将检查点存储在可靠的字典中。所以每隔 5 分钟左右,就会运行以下代码:

var profileCheckpoints = await StateManager.GetOrAddAsync<IReliableDictionary<string, DateTime>>(StateNameProfileCheckpoints);

using (var tx = StateManager.CreateTransaction())
{
    // Dictionary key is a device guid + device register id,
    // e.g.: 13cdaad8-9b8b-4fba-b336-e72e06c047ab-1.0.99.1.0.255
    var key = GetCheckpointKey(context);

    // checkpoint is a DateTime
    await profileCheckpoints.SetAsync(tx, key, checkpoint);

    // this call will sometimes take 24h to complete
    await tx.CommitAsync();
}

我们有多个后台任务在有状态服务中运行。每个后台任务都与单个硬件设备通信并运行上述代码。所有任务都使用相同的可靠字典,但仅更新特定于设备的密钥。

有些任务运行良好,并且 CommitAsync 调用很快返回。对于其他任务,CommitAsync 调用可能突然需要 24 小时才能完成。没有抛出异常,代码照常继续。一旦发生这种情况,除非我们重新启动服务,否则此任务的所有其他 CommitAsync 调用也将需要 24 小时才能完成。

集群和所有应用程序在门户中报告为健康。但是,当我查看不同节点上的事件查看器时,我看到正在记录以下警告(大约每 5 秒一次):

dropping message <some guid>, Actor = Transport, Action = ‘’, fault = FABRIC_E_CONNECTION_CLOSED_BY_REMOTE_END

知道这可能是什么原因吗?

【问题讨论】:

  • 已经大约一年了,所以这个方法应该运行了大约 365 次 ;) 你有没有弄明白这个?根据您的发现有什么要分享的吗?
  • 不幸的是,我们有点放弃了这种情况,现在将这些检查点存储在 Blob 存储中。将尝试找一些时间重新测试。

标签: azure-service-fabric


【解决方案1】:

GetCheckpointKey 是否与设备通信?莫非这是占用了一个线程并阻塞了,这意味着线程池正在耗尽。

可能抓住了稻草,但 GetCheckpointKey 上没有 await 让我有点怀疑。

【讨论】:

  • 与设备的所有通信都在上面的代码被命中时完成。 GetCheckpointKey 仅包含一个 string.Format 调用,用于连接两个字符串以获取字典键。下一个调用 (SetAsync) 仍然可以正常运行并快速完成。然后 CommitAsync 调用挂起。
猜你喜欢
  • 2012-04-15
  • 2012-01-14
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多