C# Azure触发的队列无法删除
根据和的文档,我的理解是,当排队消息失败给定次数时(在本例中为5次),它会自动从当前队列移动到中毒队列 不幸的是,我有限的经验发现这只是部分正确,因为当作业未通过最大出列计数时,它会自动添加到中毒队列中,但不会从原始队列中删除,然后在10分钟后重新处理一个显然不可更改的消息,将相同的消息添加到中毒队列中,创建重复项,但仍不删除它 当我实现自己的C# Azure触发的队列无法删除,c#,azure,azure-queues,C#,Azure,Azure Queues,根据和的文档,我的理解是,当排队消息失败给定次数时(在本例中为5次),它会自动从当前队列移动到中毒队列 不幸的是,我有限的经验发现这只是部分正确,因为当作业未通过最大出列计数时,它会自动添加到中毒队列中,但不会从原始队列中删除,然后在10分钟后重新处理一个显然不可更改的消息,将相同的消息添加到中毒队列中,创建重复项,但仍不删除它 当我实现自己的IQueueProcessorFactory类,在覆盖DeleteMessageAsync时创建一个自定义QueueProcessor时,我能够确认在抛出
IQueueProcessorFactory
类,在覆盖DeleteMessageAsync
时创建一个自定义QueueProcessor
时,我能够确认在抛出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天的时间在互联网上搜寻信息后,我正式不知所措,不知下一步该做什么或尝试什么
编辑
虽然我们最终使用了Service Bus,但值得注意的是,我们提出了一种替代方案,即从队列触发器内部自己半管理队列
这需要检查出列计数,如果它高于最大出列(重试)计数,只需返回。这将向调用者发出消息“成功”处理的信号,然后将其从队列中删除。该方法将导致几乎预期的行为,即消息将被添加到毒药队列,而10分钟后从正常队列中删除
它还有一个额外的好处,那就是继续处理包的未来版本或队列本身的更新,这些更新将修复原始问题,因为if永远不会是真的
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
}
我将根据个人经验和我在StackOverflow上看到的情况,给你一个非参考答案。对于WebJob QueueTriggerAttribute,您不是第一个遇到自动死信和遵守最大出列计数问题的人。我的建议是避免使用存储队列+队列触发器,而使用服务总线队列和服务总线触发器
作为一种消息传递技术,服务总线队列功能更加全面,成本也相当。我选择使用存储队列而不是服务总线队列的唯一真正原因是,如果需要存储超过80GB的消息,这是分区的服务总线队列限制 我遇到了相同的行为,这是由webjobs sdk(v2)和存储客户机库v8.x之间产生的错误引起的 这应该是固定的,因为。缺点是目前还没有稳定的2.1.0发布版本