Service Fabric可靠队列FabricNotReadableException

时间:2016-11-15 02:03:45

标签: azure-service-fabric

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

RunAsync方法中的这个服务有一个infinte while循环,我调用Reliable Queue来获取消息。 如果没有消息我等待5秒钟,然后重试。 我曾经使用Azure存储队列成功完成了这项工作。

但是,随着Service Fabric I成千上万的 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)并且有数千个&#34;任务被取消&#34;错误。

我在这里失踪了什么? 周期太快,SF无法及时更新其他副本? 我应该删除只留下一个副本的所有副本吗?

我应该使用新的ConcurrentQueue吗?

我在生产中遇到问题,在本地有50或1000个分区,这没什么关系。

我很困惑和困惑。 感谢

1 个答案:

答案 0 :(得分:0)

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

我建议您检查循环中的cancellationToken.IsCancelled,如果已取消,则会发出错误。

FabricNotReadableException可能由于各种原因而发生 - this question的答案有全面的解释,但外卖是

  

您可以将FabricNotReadableException视为可重复。如果您看到它,只需再次尝试呼叫,最终它将解析为NotPrimary或​​Granted。