Service Fabric 可靠队列 FabricNotReadableException

Service Fabric Reliable Queues FabricNotReadableException

我有一个包含 1000 个分区和 1 个副本的有状态服务。

RunAsync 方法中的此服务有一个无限循环,我在其中调用可靠队列来获取消息。 如果没有消息,我等待 5 秒,然后重试。 我曾经成功地使用 Azure 存储队列来做到这一点。

但是对于 Service Fabric,我收到了数千个 FabricNotReadableExceptions,服务变得不稳定,我无法更新或删除它,我需要取消整个簇。 我尝试更新它,但在 18 小时后它仍然卡住,所以我正在做的事情出现了严重的错误。

这是方法代码:

public async Task<QueueObject> DeQueueAsync(string queueName)
        {
    var q = await StateManager.GetOrAddAsync<IReliableQueue<string>>(queueName);
        using (var tx = StateManager.CreateTransaction())
        {
            try
            {
                var dequeued = await q.TryDequeueAsync(tx);
                if (dequeued.HasValue)
                {
                    await tx.CommitAsync();
                    var result = dequeued.Value;
                    return JSON.Deserialize<QueueObject>(result);
                }
                else
                {
                    return null;
                }
            }
            catch (Exception e)
            {
                ServiceEventSource.Current.ServiceMessage(this, $"!!ERROR!!: {e.Message} - Partition: {Partition.PartitionInfo.Id}");
                return null;
            }
        }}

这是 RunAsync

    protected override async Task RunAsync(CancellationToken cancellationToken)
{
    while (true)
    {
        var message = await DeQueueAsync("MyQueue");
        if (message != null)
        {
            //process, takes around 500ms
        }
        else
        {
            Thread.Sleep(5000);
        }
    }
}

我还用 Task.Delay 更改了 Thread.Sleep(5000),并且出现了数千个 "A task was canceled" 错误。

我在这里缺少什么? 是不是周期太快了,顺丰不能及时更新其他副本? 我应该删除所有副本只留下一个吗?

我应该改用新的 ConcurrentQueue 吗?

我在生产和本地有 50 或 1000 个分区的问题,没关系。

我很困惑。 谢谢

您需要遵守传递给 RunAsync 实施的 cancellationToken。当 Service Fabric 出于任何原因(包括升级)想要停止您的服务时,它会取消令牌,并且在取消令牌后它将无限期地等待 RunAsync 到 return。这可以解释为什么您无法升级您的应用程序。

我建议在你的循环中检查 cancellationToken.IsCancelled,如果它被取消了就退出。

FabricNotReadableException 的发生可能有多种原因 - 的答案有全面的解释,但要点是

You can consider FabricNotReadableException retriable. If you see it, just try the call again and eventually it will resolve into either NotPrimary or Granted.