我们可以防止 Service Fabric 中 ReliableQueue 的死锁和超时吗?

Can we prevent deadlocks and timeouts on ReliableQueue's in Service Fabric?

我们在 Service Fabric 中有一个有状态服务,其中包含一个 RunAsync 方法和几个服务调用。

一个服务调用允许在 ReliableQueue 中排队一些东西

using(ITransaction tx = StateManager.CreateTransaction())
{
  await queue.EnqueueAsync(tx, message);
  queueLength = await queue.GetCountAsync(tx);
  await tx.CommitAsync();
}

另一方面,RunAsync 尝试使事物出列:

using(ITransaction tx = StateManager.CreateTransaction())
{
  await queue.TryDequeueAsync(tx);
  queueLength = await queue.GetCountAsync(tx);
  await tx.CommitAsync();
}

GetCountAsync 似乎会导致死锁,因为两个事务相互阻塞。如果我们改变顺序会有帮助吗:所以首先计算然后 dequeue/enqueue?

在两个不同的地方进行两个事务不应导致死锁,因为它们就像互斥体一样。但是,导致它们的原因是在交易中创建交易。

也许这就是正在发生的事情?我最近养成了命名创建事务事务的函数的习惯,即 DoSomethingTransactionalAsync,如果它是一个私人助手,我通常会创建两个版本,一个接受 tx,一个创建 tx。

例如:

AddToProcessingQueueAsync(ITransaction tx, int num)AddToProcessingQueueTransactionalAsync(int num)

这可能是因为今天的 ReliableQueue 是严格的 FIFO,并且一次只允许一个 reader 或写入器。您可能没有看到死锁,您看到的是超时(如果不是这种情况,请纠正我)。没有真正的方法来防止超时,除了:

  • 确保事务不会长期存在 - 任何超过您需要的时间都会阻塞队列中的其他工作。
  • 增加默认事务超时时间(默认4秒,可以传入不同的值)

重新排序应该不会造成任何改变。