2017-02-23 99 views
1

根據herehere的文檔,許多SO問題如this one,我的理解是當排隊的消息在給定次數內失敗(在本例中爲5次)時,它會從當前自動排隊並進入毒性隊列。Azure觸發隊列無法刪除

不幸的是,我有限的經驗發現這只是部分正確的,因爲當作業失敗最大出隊計數時,它會自動添加到毒性隊列中,但它不會從原始隊列中刪除,然後顯然會被重新處理10分鐘後不可更改,將相同的消息添加到毒物隊列中,創建重複項,仍然不會將其刪除。

當我實現我自己的IQueueProcessorFactory類,創建一個自定義QueueProcessor同時覆蓋DeleteMessageAsync,我能夠證實該方法被調用的時候,拋出異常的5倍和方法完成且沒有異常,但在隊列遺體的消息。我也嘗試刪除正常和毒素隊列。

我正在使用的代碼:

public class Program 
{ 
    private const string QUEUE_NAME = "some-queue"; 

    // Please set the following connection strings in app.config for this WebJob to run: 
    // AzureWebJobsDashboard and AzureWebJobsStorage 
    static void Main() 
    { 
     var config = new JobHostConfiguration(); 

     config.Queues.QueueProcessorFactory = new CustomFactory(); 
     var host = new JobHost(config); 
     // The following code ensures that the WebJob will be running continuously 
     host.RunAndBlock(); 
    } 

    private class CustomFactory : IQueueProcessorFactory 
    { 
     public QueueProcessor Create(QueueProcessorFactoryContext context) 
     { 
      return new CustomQueueProcessor(context); 
     } 

     private class CustomQueueProcessor : QueueProcessor 
     { 
      public CustomQueueProcessor(QueueProcessorFactoryContext context) : base(context) 
      { 

      } 

      protected override Task DeleteMessageAsync(CloudQueueMessage message, CancellationToken cancellationToken) 
      { 
       return base.DeleteMessageAsync(message, cancellationToken); 
      } 
     } 
    } 

    public static void QueueTrigger([QueueTrigger(QUEUE_NAME)] CloudQueueMessage message) 
    { 
     Console.WriteLine($"Processing message: {message.AsString}"); 
     throw new Exception("test exception"); 
    } 
} 

一切正常,除了該消息仍然在原來的隊列中。我假設,並希望,錯誤是在我的最後,或者說,這是愚蠢的,我只是忽略了,因爲我是排隊的新手,但花了差不多2天的時間在互聯網上搜索信息,我正式陷入了虧損之中,接下來做什麼或嘗試。

編輯

雖然我們確實結束了服務總線去,這是值得注意的是,我們想出了這是一種替代從隊列觸發內半管理隊列自己。

這需要檢查出列計數,如果它超出最大出列(重試)計數,只需返回。這將向調用者發信號通知消息「成功」處理,然後將其從隊列中移除。該方法幾乎會導致預期的行爲,因爲消息將在10分鐘後從正常隊列中移除時被添加到毒性隊列中。

它還有一個額外的好處,就是可以繼續使用未來版本的軟件包或對隊列本身的更新,以解決原始問題,因爲如果根本不會是真的。

public class Program 
{ 
    private const int MAX_DEQUEUE_COUNT = 5; 

    static void Main() 
    { 
     var config = new JobHostConfiguration(); 
     ... 
     config.Queues.MaxDequeueCount = MAX_DEQUEUE_COUNT; 
     ... 
    } 

    public static void QueueTrigger([QueueTrigger("some-queue")] CloudQueueMessage message) 
    { 
     if (message.DequeueCount > MAX_DEQUEUE_COUNT) 
     { 
      // prevents the message from indefinitely retrying every 10 minutes and ultimately creating duplicates within the poison queue. 
      return; 
     } 

     // do stuff 
    } 

回答

0

我即將給你一個基於個人經驗和我在StackOverflow上看到的非參考答案。您不是第一個在WebJob QueueTriggerAttributes方面遇到自動死鎖問題並遵守最大出隊計數的人。我的建議是避開存儲隊列+隊列觸發器的片狀,以利用服務總線隊列和服務總線觸發器。

作爲一種消息傳遞技術,服務總線隊列功能更加全面,且具有可比性。我選擇通過服務總線隊列使用存儲隊列的唯一真正原因是如果您需要存儲超過80GB的消息,這是服務總線隊列限制與分區。

0

我遇到了相同的行爲,它是由webjobs sdk(v2)和存儲客戶端庫v8.x之間產生的錯誤引起的。

這應該從2.1.0-beta1-10851開始修復。缺點是目前還沒有穩定的2.1.0發佈版本。