Azure webjob 似乎不尊重 MaxDequeueCount 属性
Posted
技术标签:
【中文标题】Azure webjob 似乎不尊重 MaxDequeueCount 属性【英文标题】:Azure webjob not appearing to respect MaxDequeueCount property 【发布时间】:2017-07-04 17:52:35 【问题描述】:我有一个带有多个队列触发函数的 Azure webjob。 https://docs.microsoft.com/en-us/azure/app-service-web/websites-dotnet-webjobs-sdk-storage-queues-how-to#config 的 SDK 文档将 MaxDequeueCount
属性定义为:
在将队列消息发送到某个队列之前的最大重试次数 中毒队列(默认为 5)。
但我没有看到这种行为。在我的网络作业中,我有:
JobHostConfiguration config = new JobHostConfiguration();
config.Queues.MaxDequeueCount = 1;
JobHost host = new JobHost(config);
host.RunAndBlock();
然后我有一个队列触发函数,我在其中抛出异常:
public void ProcessQueueMessage([QueueTrigger("azurewejobtestingqueue")] string item, TextWriter logger)
if ( item == "exception" )
throw new Exception();
查看 webjobs 仪表板,我看到 SDK 进行了 5 次尝试(如上所述,默认值为 5):
在第 5 次尝试后,邮件被移至毒物队列。我希望看到 1 次重试(或没有重试?)而不是 5 次。
更新:为 Web 应用启用详细日志记录,并选择将这些日志保存到 Azure blob 容器。在azure-jobs-host-archive
容器中找到了一些与我的问题相关的日志。下面是一个显示出列计数为 96 的项目的示例:
"Type": "FunctionCompleted",
"EndTime": "2017-02-22T00:07:40.8133081+00:00",
"Failure":
"ExceptionType": "Microsoft.Azure.WebJobs.Host.FunctionInvocationException",
"ExceptionDetails": "Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: ItemProcessor.ProcessQueueMessage ---> MyApp.Exceptions.MySpecialAppExceptionType: Exception of type 'MyApp.Exceptions.MySpecialAppExceptionType' was thrown.
,
"ParameterLogs": ,
"FunctionInstanceId": "1ffac7b0-1290-4343-8ee1-2af0d39ae2c9",
"Function":
"Id": "MyApp.Processors.ItemProcessor.ProcessQueueMessage",
"FullName": "MyApp.Processors.ItemProcessor.ProcessQueueMessage",
"ShortName": "ItemProcessor.ProcessQueueMessage",
"Parameters": [
"Type": "QueueTrigger",
"AccountName": "MyStorageAccount",
"QueueName": "stuff-processor",
"Name": "sourceFeedItemQueueItem"
,
"Type": "BindingData",
"Name": "dequeueCount"
,
"Type": "ParameterDescriptor",
"Name": "logger"
]
,
"Arguments":
"sourceFeedItemQueueItem": "\"SourceFeedUpdateID\":437530,\"PodcastFeedID\":\"2d48D2sf2\"",
"dequeueCount": "96",
"logger": null
,
"Reason": "AutomaticTrigger",
"ReasonDetails": "New queue message detected on 'stuff-processor'.",
"StartTime": "2017-02-22T00:07:40.6017341+00:00",
"OutputBlob":
"ContainerName": "azure-webjobs-hosts",
"BlobName": "output-logs/1ffd3c7b012c043438ed12af0d39ae2c9.txt"
,
"ParameterLogBlob":
"ContainerName": "azure-webjobs-hosts",
"BlobName": "output-logs/1cf2c1b012sa0d3438ee12daf0d39ae2c9.params.txt"
,
"LogLevel": "Info",
"HostInstanceId": "d1825bdb-d92a-4657-81a4-36253e01ea5e",
"HostDisplayName": "ItemProcessor",
"SharedQueueName": "azure-webjobs-host-490daea03c70316f8aa2509438afe8ef",
"InstanceQueueName": "azure-webjobs-host-d18252sdbd92a4657d1a436253e01ea5e",
"Heartbeat":
"SharedContainerName": "azure-webjobs-hosts",
"SharedDirectoryName": "heartbeats/490baea03cfdfd0416f8aa25aqr438afe8ef",
"InstanceBlobName": "zd1825bdbdsdgga465781a436q53e01ea5e",
"ExpirationInSeconds": 45
,
"WebJobRunIdentifier":
"WebSiteName": "myappengine",
"JobType": "Continuous",
"JobName": "ItemProcessor",
"RunId": ""
我正在进一步寻找的是日志,这些日志将向我显示特定队列项目的详细信息,其中处理成功(因此从队列中删除)或由于异常而失败并被放置在毒队列中。到目前为止,我还没有找到任何显示该详细信息的日志。上面输出中引用的日志文件不包含此类数据。
更新 2:查看我的毒药队列的状态,它似乎是一把确凿的证据,但我太密集了,无法将 2 和 2 放在一起。查看下面队列的屏幕截图,您可以在其中多次看到 ID(左列)431210
的消息。它多次出现的事实告诉我原始队列中的消息失败不正确。
【问题讨论】:
你是在 Azure 上运行还是在本地运行? @Rob 在 Azure 上运行。 我们也在做同样的事情,如果你降级到 7.2.1 这个问题不会发生。然而,降级是一个糟糕的解决方案。对我们来说这不起作用,因为我们使用 Umbraco,它需要更高版本作为 nuget.org/packages/UmbracoFileSystemProviders.Azure 的一部分,您可以在依赖项 WindowsAzure.Storage (>= 8.7.0) nuget.org/packages/WindowsAzure.Storage 中看到它 【参考方案1】:正如 Rob W 所述,使用 WindowsAzure.Storage > 7.1.2 时存在此问题。该问题显然已在 issue #1141 中修复,但尚未发布。
贡献者asifferman 在issue #985 上分享了@987654323@。这似乎可以解决问题(它对我来说非常有效)。
如果链接失效,并且为了满足 SO 规则,这里是帖子以及代码 sn-p:
对于那些(像我一样)迫不及待想要获得下一个版本的人 WebJobs SDK 可与最新版本的 Azure 存储一起使用,以及 根据@brettsam 的解释,您可以简单地编写一个自定义 在 CustomQueueProcessorFactory 中创建一个新的 CloudQueueMessage CopyMessageToPoisonQueueAsync。
namespace ConsoleApplication1
using Microsoft.Azure.WebJobs.Host.Queues;
using Microsoft.WindowsAzure.Storage.Queue;
using System.Threading;
using System.Threading.Tasks;
public class CustomQueueProcessorFactory : IQueueProcessorFactory
public QueueProcessor Create(QueueProcessorFactoryContext context)
return new CustomQueueProcessor(context);
private class CustomQueueProcessor : QueueProcessor
public CustomQueueProcessor(QueueProcessorFactoryContext context)
: base(context)
protected override Task CopyMessageToPoisonQueueAsync(CloudQueueMessage message, CloudQueue poisonQueue, CancellationToken cancellationToken)
var newMessage = new CloudQueueMessage(message.Id, message.PopReceipt);
newMessage.SetMessageContent(message.AsBytes);
return base.CopyMessageToPoisonQueueAsync(newMessage, poisonQueue, cancellationToken);
然后在您的 Main 中,您只需设置自定义队列处理器 作业主机配置中的工厂:
var config = new JobHostConfiguration();
config.Queues.QueueProcessorFactory = new CustomQueueProcessorFactory();
我可以让它与 WindowsAzure.Storage 8.1.1 和 Microsoft.Azure.WebJobs 2.0.0。希望对您有所帮助!
【讨论】:
【参考方案2】:如果您仍在寻找答案,我们尝试了列出的一些答案,但均未成功。事实证明,这是 Storage sdk (WindowsAzure.Storage) 和 Webjob sdk (Microsoft.Azure.WebJobs) 的版本问题。为了解决这个问题,我们最终不得不将我们的 Storage sdk 版本降级到 7.2.1(我们最近升级到了 8.1.1)。根据下面的文章,工程师们现在已经意识到了这些问题,并希望能尽快解决:
https://github.com/Azure/azure-webjobs-sdk/issues/1045
【讨论】:
成功了!完美地描述了它。 也面临类似的问题,但最大出队计数对我们来说效果很好。在 x 出列计数后,消息会正确移动到毒队列。但在那之后,我们每 10 分钟就会在毒物队列中看到同一消息的一个新条目。问题似乎只发生在 WebJobs SDK 1.1.2 和 Azure Storage V8.0.1(这是我们的例子)问题被引用 @github.com/Azure/azure-webjobs-sdk/issues/985 我们可能会在它修复后降级......【参考方案3】:如果我对其进行配置,MaxDequeueCount 属性对我来说可以正常工作。
所以很奇怪,它不适合你。当我设置
config.Queues.MaxDequeueCount = 2;
然后我得到了预期的结果请参考截图。
我们也可以使用dequeueCount
来控制重试次数。以下是演示代码,无需尝试。
public void ProcessQueueMessage([QueueTrigger("queue")] string item, int dequeueCount, TextWriter logger)
if (dequeueCount == 1)
if (item == "exception")
throw new Exception();
logger.WriteLine($"NewMsge: item");
Console.WriteLine($"NewMsge: item");
日志信息请参考截图
【讨论】:
【参考方案4】:我怀疑这是因为您实际上并没有运行您认为自己在 Azure 中的二进制文件。这也让我陷入了困境。
当您在 Azure 上运行触发式 WebJobs 时,发布新版本的 WebJob 不会导致旧的触发式 WebJob 立即卸载并启动新的 WebJob。如果您查看您的 WebJob 日志,我怀疑您在重新发布时不会看到重新启动。
这是因为 Kudu 默认将所有 WebJob 文件复制到临时目录并执行它们。来自Kudu WebJob docs:
WebJob 被复制到 %TEMP%\jobsjob 下的临时目录 typejob namerandom name 并从那里运行这个选项 防止原始 WebJob 二进制文件被锁定,这可能 导致重新部署 WebJob 的问题。例如更新 .exe 文件 当前正在运行。
我在确保新发布的触发式 WebJob 实际运行方面取得的唯一成功是执行以下操作:
登录 Kudu 控制台。这是https://yourappname.scm.azurewebsites.net。你将使用与登录 Azure 门户时相同的凭据。
登录后,单击顶部的 Process Explorer 菜单选项。找到当前正在运行的 WebJob 进程,然后将其终止。
FTP 到您的 Web 应用程序。浏览到包含您的 WebJob 代码的目录,然后将其删除。它应该在 /app_data/jobs/triggered/[your webjob name] 下。
然后我跳到门户,浏览到托管 WebJob 的 Web 应用管理刀片,单击 WebJobs 菜单选项,并确认旧的 WebJob 不再存在。
从 Visual Studio 发布我的新 WebJob。
这应该可以保证您正在运行您发布的代码。希望这可以帮助。
【讨论】:
我想我以前见过这种行为。但是,我确实会在发布后立即定期验证我的 webjob 的运行状态,并且在所有情况下,作业都会重新启动。无论如何,我已经看到这个问题很长一段时间了,但巧合的是(出于其他原因)前几天我进入 Azure 门户,删除了与该网站关联的 webjobs,删除了 wwwroot 的内容,然后做了完全重新部署...我刚刚发现的东西-在某些情况下,我会重试> 5次。所以我不明白这个数字是如何确定的。 您是否正在运行多个 WebJob 实例? 没有网站(因此 webjob)是单个实例(并且 BatchSize=1)。但是 webjobs sdk 保证如果 webjob 的多个实例正在运行,那么只有一个实例会从队列中选择一个给定的项目。顺便说一句,我刚刚添加了一些 add'l 日志记录来报告 MaxDequeueCount 属性的值,以验证它是我设置的值并且它没有被某种方式覆盖。 伙计们,如果你们可以一起获得一个 repro,请在我们的 repo 中记录一个错误github.com/Azure/azure-webjobs-sdk/issues。出队计数不应超过最大值 - 我还没有看到这种情况发生。 @matthewc 我想用尽可能多的建设性信息记录这个错误。您能否快速查看我在***.com/questions/42381354/… 的后续帖子,我在其中询问了我正在寻找的与网络作业相关的日志信息?【参考方案5】:我看到了同样的情况,即消息超过了最大出队计数。我稍后会发布更多详细信息,但我也看到看起来非常大的数字最终进入了毒药队列。所以我怀疑它在 5 之后添加到毒物队列中,但尝试更多最终会在毒物队列中(数百个)。
【讨论】:
您是否偶然看到同一原始消息的多个有害消息? 是的。它仍在为相同的原始消息创建(多个)消息,但也将其放回标准队列中。所以它似乎正在正确地毒化,但没有从原始队列中删除。【参考方案6】:对于使用 Azure WebJobs v3.x SDK 的任何人:
在 v3.x 中,hosts.json 不适用于 WebJob。
相反,版本 3.x 使用标准 ASP.NET Core API,因此您需要使用 ConfigureWebJobs 方法对其进行配置:
static async Task Main()
var builder = new HostBuilder();
builder.ConfigureWebJobs(b =>
b.AddAzureStorageCoreServices();
b.AddAzureStorage(a =>
a.BatchSize = 8;
a.NewBatchThreshold = 4;
a.MaxDequeueCount = 4;
a.MaxPollingInterval = TimeSpan.FromSeconds(15);
);
);
var host = builder.Build();
using (host)
await host.RunAsync();
文档:https://docs.microsoft.com/pt-pt/azure/app-service/webjobs-sdk-how-to#queue-storage-trigger-configuration
【讨论】:
以上是关于Azure webjob 似乎不尊重 MaxDequeueCount 属性的主要内容,如果未能解决你的问题,请参考以下文章
为啥我需要在 Azure 管理门户中而不是在我的 WebJob 的 App.config 中为 WebJobs 配置连接字符串?
Azure 触发的 Webjob - 检测 webjob 何时停止
命名空间“Microsoft.Azure.WebJobs”中不存在类型或命名空间名称“TableAttribute”