根據here和here的文檔,許多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
}