Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Azure 移动到有毒队列的队列消息仍显示为队列计数,但保持隐藏状态_Azure_Azure Webjobs_Azure Webjobssdk - Fatal编程技术网

Azure 移动到有毒队列的队列消息仍显示为队列计数,但保持隐藏状态

Azure 移动到有毒队列的队列消息仍显示为队列计数,但保持隐藏状态,azure,azure-webjobs,azure-webjobssdk,Azure,Azure Webjobs,Azure Webjobssdk,我正在测试我正在构建的Webjob的有毒消息处理 除了一件奇怪的事情外,一切似乎都在按预期进行: 当消息移动到“-poison”队列时,其重影似乎在主作业队列中保持隐藏(不可见)。这意味着,如果将6条有害消息移动到“-poison”队列,storage explorer将显示“显示队列中6条消息中的0条”。我在存储资源管理器中看不到6条隐藏消息 我试图删除作业队列并重新创建它,但在运行测试后,奇怪的问题仍然发生。存储资源管理器显示“显示队列中6封邮件中的0封” 幕后发生了什么 更新1 我做了一些

我正在测试我正在构建的Webjob的有毒消息处理

除了一件奇怪的事情外,一切似乎都在按预期进行:

当消息移动到“-poison”队列时,其重影似乎在主作业队列中保持隐藏(不可见)。这意味着,如果将6条有害消息移动到“-poison”队列,storage explorer将显示“显示队列中6条消息中的0条”。我在存储资源管理器中看不到6条隐藏消息

我试图删除作业队列并重新创建它,但在运行测试后,奇怪的问题仍然发生。存储资源管理器显示“显示队列中6封邮件中的0封”

幕后发生了什么

更新1

我做了一些调查,我认为WebJob SDK没有删除毒药消息

我浏览了WebJob SDK源代码,我认为这行代码由于某种原因没有被执行:

以下是我的功能,可以帮助再现问题:

public class Functions
{
    public static void ProcessQueueMessage([QueueTrigger("%QueueName%")] string message, TextWriter log)
    {
        if (message.Contains("Break"))
        {
            throw new Exception($"Error while processing message {message}");
        }

        log.WriteLine($"Processed message {message}");
    }

}
更新2

以下是我正在使用的WebJob SDK:


我也有同样的问题

问题是当有毒队列中的消息副本在没有可见性时间的情况下通过引用传递时,以及当尝试从原始队列中删除消息时,服务返回404 not found。是azure webjobs sdk中的一个问题,解决方案是进行此更改

await AddMessageAndCreateIfNotExistsAsync(poisonQueue, new CloudQueueMessage(message.AsString), cancellationToken);

我们等待此修复程序的新版本

定制解决方案

要解决此问题,请创建您自己的CustomProcessor,并在CopyMessageTopoQueueAsync函数中从原始邮件创建新的CloudMessage以传入毒药队列,请参见下面的示例

var config = new JobHostConfiguration
config.Queues.QueueProcessorFactory = new CustomQueueProcessorFactory();

public QueueProcessor Create(QueueProcessorFactoryContext context)
    {
        // demonstrates how the Queue.ServiceClient options can be configured
        context.Queue.ServiceClient.DefaultRequestOptions.ServerTimeout = TimeSpan.FromSeconds(30);

        // demonstrates how queue options can be customized
        context.Queue.EncodeMessage = true;

        // return the custom queue processor
        return new CustomQueueProcessor(context);
    }

    /// <summary>
    /// Custom QueueProcessor demonstrating some of the virtuals that can be overridden
    /// to customize queue processing.
    /// </summary>
    private class CustomQueueProcessor : QueueProcessor
    {
        private QueueProcessorFactoryContext _context;
        public CustomQueueProcessor(QueueProcessorFactoryContext context)
            : base(context)
        {
            _context = context;
        }

        public override async Task CompleteProcessingMessageAsync(CloudQueueMessage message, FunctionResult result, CancellationToken cancellationToken)
        {
            await base.CompleteProcessingMessageAsync(message, result, cancellationToken);
        }
        protected override async Task CopyMessageToPoisonQueueAsync(CloudQueueMessage message, CloudQueue poisonQueue, CancellationToken cancellationToken)
        {
            var msg = new CloudQueueMessage(message.AsString);
            await base.CopyMessageToPoisonQueueAsync(msg, poisonQueue, cancellationToken);
        }
        protected override void OnMessageAddedToPoisonQueue(PoisonMessageEventArgs e)
        {
            base.OnMessageAddedToPoisonQueue(e);
        }
    }
var config=new JobHostConfiguration
config.Queues.QueueProcessorFactory=新的CustomQueueProcessorFactory();
公共QueueProcessor创建(QueueProcessorFactoryContext上下文)
{
//演示如何配置Queue.ServiceClient选项
context.Queue.ServiceClient.DefaultRequestOptions.ServerTimeout=TimeSpan.FromSeconds(30);
//演示如何自定义队列选项
context.Queue.EncodeMessage=true;
//返回自定义队列处理器
返回新的CustomQueueProcessor(上下文);
}
/// 
///自定义QueueProcessor演示了一些可以重写的虚拟机
///自定义队列处理。
/// 
私有类CustomQueueProcessor:QueueProcessor
{
专用QueueProcessorFactoryContext\u context;
公共CustomQueueProcessor(QueueProcessorFactoryContext上下文)
:基本(上下文)
{
_上下文=上下文;
}
公共重写异步任务CompleteProcessingMessageAsync(CloudQueueMessage消息、FunctionResult结果、CancellationToken CancellationToken)
{
wait base.CompleteProcessingMessageAsync(消息、结果、取消令牌);
}
受保护的重写异步任务CopyMessageToPoisonQueueAsync(CloudQueueMessage消息、CloudQueue中毒队列、CancellationToken CancellationToken)
{
var msg=newcloudqueuemessage(message.AsString);
wait base.CopyMessageToPoisonQueueAsync(消息、中毒队列、取消令牌);
}
在MessageAddedTopisoQueue上受保护的覆盖无效(TownMessageEventArgs e)
{
基于消息的分布式查询(e);
}
}

据我所知,azure存储SDK 8.+与azure webjobs SDK2.0()不兼容

如果使用storage SDK 8.+毒药消息将保持未删除状态,但不可见

解决方法是使用低azure存储SDK 7.2.1

它将很好地工作


这个问题将在未来的SDK版本中得到解决。

对于仍然存在此问题的任何人。这应该是固定的,因为。缺点是目前还没有稳定的2.1.0发布版本。

是否仅在Storage Explorer上显示“6”?问题可能就在那里only@pollirrata,存储资源管理器始终显示准确的正确计数。所以我们不知道WebJob SDK移动到的消息有什么特殊之处-中毒队列?他们有特殊的隐藏标志吗?据我所知,webjob SDK最多会调用5次函数(默认值)来处理队列消息。如果第五次尝试失败,消息将被移动到中毒队列。因此,队列消息将删除并移动到中毒队列。我也在我的电脑上写了一个测试演示,效果很好。你可以发布你的webjob的函数和配置代码吗。它将帮助我们重现您的问题并找到解决方案。@BrandoZhang MSFT,谢谢您的帮助。我更新了我的问题,希望它能帮助你重新制作这个问题。请让我知道如果你需要任何细节。我已经根据你的代码写了一个测试,它工作得很好。如果我将“AAABreak”队列消息添加到“queue”,它会将消息移动到“queue poison”队列。您能告诉我您使用的webjob SDK版本以及程序中的post更多详细信息代码吗。cs的主要方法?是否已修复?鉴于我们有一个2.2.0稳定版本,现在应该已修复,但我尚未对其进行测试。SDK的后续版本是否最终修复了此问题?