我们可以防止 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秒,可以传入不同的值)
重新排序应该不会造成任何改变。
我们在 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秒,可以传入不同的值)
重新排序应该不会造成任何改变。