2016-11-15 69 views
0

我有一個有1000個分區和1個副本的有狀態服務。服務結構可靠隊列FabricNotReadableException

RunAsync方法中的此服務在週期中有一個infinite,我稱其爲Reliable Queue來獲取消息。 如果沒有消息,我等待5秒鐘,然後重試。 我曾經用Azure存儲隊列完成這項工作,並取得了成功。

但隨着服務結構我得到成千上萬的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任務是取消「錯誤。

我在這裏錯過了什麼? 循環太快,SF無法及時更新其他副本? 我應該刪除所有副本只剩下一個副本嗎?

我應該使用新的ConcurrentQueue嗎?

我在生產和本地有50或1000分區的問題,無所謂。

我困惑和困惑。 謝謝

回答

0

您需要兌現傳遞到您的RunAsync實施的cancellationToken。服務結構會因爲任何原因(包括升級)而停止服務時取消該令牌,並且在取消令牌後它將無限期地等待RunAsync返回。這可以解釋爲什麼你不能升級你的應用程序。

我建議在你的循環中檢查cancellationToken.IsCancelled,如果它已被取消,則會顯示出來。

FabricNotReadableException情況可能由多種原因 - 答案this question有一個全面的解釋,但外賣是

你可以考慮FabricNotReadableException retriable。如果你看到它,只需再次嘗試呼叫,最終它將解析爲NotPrimary或​​授予。

+0

哦,我欠你一杯啤酒。這是造成世界問題的取消令牌。謝謝 –