Azure 函数可见性超时
Azure function visibilityTimeout
当我阅读有关 visibilityTimeout 的文档时:https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue#host-json 它说 "The time interval between retries when processing of a message fails."。我的理解是,如果超时设置为 30 秒并且我的函数运行了 1 分钟但在这 1 分钟内没有失败,则消息不会对队列中的其他人可见。但是当我通过其他来源 (Whosebug fx) 阅读它时,它告诉我相反的情况,当函数的执行时间超过超时时,即使函数仍在处理消息,消息也会变得可见。
真相是什么?超时是否仅在函数不再 运行 时才相关(并且可能已经失败),或者即使函数仍然是 运行,消息是否会再次可见?
没有意义的是,如果我们假设消息在达到超时时变得可见,那么默认超时是 00:00:00,这意味着消息在它出现的同时可见出列。这与 3. 党派人士所说的相矛盾。
我对此有点困惑。
我已经用
测试过这个
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Queue;
namespace WorkerFunctions
{
public static class WorkerFunctions
{
[FunctionName("WorkerFunction1")]
public static async Task Function1(
[QueueTrigger("outputQueue")]
CloudQueueMessage item,
[Queue("outputQueue")]
CloudQueue outputQueue,
DateTimeOffset nextVisibleTime,
DateTimeOffset expirationTime,
DateTimeOffset insertionTime,
ILogger log)
{
log.LogInformation("########## Function 1 ###############");
log.LogInformation($"NextVisibleTime: {nextVisibleTime}");
log.LogInformation($"NextVisibleTime: {(nextVisibleTime-insertionTime).TotalSeconds}");
log.LogInformation($"C# Queue trigger function processed: {item.AsString}");
Thread.Sleep(TimeSpan.FromMinutes(20));
}
[FunctionName("WorkerFunction2")]
public static async Task Function2(
[QueueTrigger("outputQueue")]
CloudQueueMessage item,
[Queue("outputQueue")]
CloudQueue outputQueue,
DateTimeOffset nextVisibleTime,
DateTimeOffset expirationTime,
DateTimeOffset insertionTime,
ILogger log)
{
log.LogInformation("########## Function 2 ###############");
log.LogInformation($"NextVisibleTime: {nextVisibleTime}");
log.LogInformation($"NextVisibleTime: {(nextVisibleTime - insertionTime).TotalSeconds}");
log.LogInformation($"C# Queue trigger function processed: {item.AsString}");
Thread.Sleep(TimeSpan.FromMinutes(20));
}
}
}
有了这个主机文件
{
"version": "2.0",
"extensions": {
"queues": {
"maxPollingInterval": "00:00:02",
"visibilityTimeout": "00:00:10",
"batchSize": 16,
"maxDequeueCount": 5,
"newBatchThreshold": 8
}
}
}
当我将一条简单消息放入队列并让它 运行 时,我看到以下内容:
- 抓住它的函数,在睡眠结束前不会释放它
- 我在日志中看不到租约已续订,但它似乎是在幕后发生的
这告诉我什么:
- 如果函数没有失败,或者主机没有失败,那么租约将根据以下条件自动续订:
- 当达到可见性超时且函数为 运行ning 时,消息不会 "readded" 进入队列
- 关于 visibilityTimeout 的文档是真实的:"The time interval between retries when processing of a message fails."(来自 https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue#hostjson-settings)
我没有保存任何与此相矛盾的 3.party 链接(抱歉,我没有保存这些链接),但它们存在。我希望有人能回答这个问题,这样我就可以得到澄清。
这里似乎实际上使用了两个不同的可见性超时值。两者都由 Azure WebJobs SDK 设置,但只有一个是可配置的。
当函数失败时
queues.visibilityTimeout
配置选项更恰当地命名为 retryDelay
。
当函数抛出异常或因其他类型的错误而失败时,消息将返回到队列中以供重试。该消息与配置的 visibilityTimeout
(参见 here)一起返回,这会延迟函数下一次尝试 运行.
的时间
这使您的应用程序能够处理暂时性错误。例如,如果电子邮件 API 或其他外部服务暂时关闭。通过延迟重试,服务有可能重新联机以进行下一次功能尝试。
重试限制为 maxDequeueCount
次尝试(默认为 5 次),然后将消息移至 Poison Queue。
虽然函数是运行宁
当 QueueTrigger
绑定 运行 函数时,它将消息出列,可见性超时为 10 分钟(hard-coded here). It then sets a timer to extend the visibility window when it reaches half-time as long as the function is running (see the timer and visibility update 在源中)。
通常您不需要担心这个,只要您的函数正确使用 CancellationToken
s 即可。仅当 Azure Function/WebJob 主机没有到达 shut down gracefully 时,这 10 分钟的超时才有意义。例如:
- 有人在虚拟主机上“拔掉插头”
- 如果函数在 scale-in or other Azure shutdown events
期间没有及时响应 CancellationToken
因此,只要函数仍然是 运行ning,消息就会在队列中保持隐藏状态。
验证
我做了一个类似的实验来检查:
[FunctionName("SlowJob")]
public async Task Run(
[QueueTrigger("slow-job-queue")] CloudQueueMessage message,
ILogger log)
{
for (var i = 0; i < 20; i++)
{
log.LogInformation($"Next visible {i}: {message.NextVisibleTime}");
await Task.Delay(60000);
}
}
输出:
Next visible 0: 5/11/2020 7:49:24 +00:00
Next visible 1: 5/11/2020 7:49:24 +00:00
Next visible 2: 5/11/2020 7:49:24 +00:00
Next visible 3: 5/11/2020 7:49:24 +00:00
Next visible 4: 5/11/2020 7:49:24 +00:00
Next visible 5: 5/11/2020 7:54:24 +00:00
Next visible 6: 5/11/2020 7:54:24 +00:00
Next visible 7: 5/11/2020 7:54:24 +00:00
Next visible 8: 5/11/2020 7:54:24 +00:00
Next visible 9: 5/11/2020 7:54:24 +00:00
Next visible 10: 5/11/2020 7:59:24 +00:00
Next visible 11: 5/11/2020 7:59:24 +00:00
...
当我阅读有关 visibilityTimeout 的文档时:https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue#host-json 它说 "The time interval between retries when processing of a message fails."。我的理解是,如果超时设置为 30 秒并且我的函数运行了 1 分钟但在这 1 分钟内没有失败,则消息不会对队列中的其他人可见。但是当我通过其他来源 (Whosebug fx) 阅读它时,它告诉我相反的情况,当函数的执行时间超过超时时,即使函数仍在处理消息,消息也会变得可见。
真相是什么?超时是否仅在函数不再 运行 时才相关(并且可能已经失败),或者即使函数仍然是 运行,消息是否会再次可见?
没有意义的是,如果我们假设消息在达到超时时变得可见,那么默认超时是 00:00:00,这意味着消息在它出现的同时可见出列。这与 3. 党派人士所说的相矛盾。
我对此有点困惑。
我已经用
测试过这个using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Queue;
namespace WorkerFunctions
{
public static class WorkerFunctions
{
[FunctionName("WorkerFunction1")]
public static async Task Function1(
[QueueTrigger("outputQueue")]
CloudQueueMessage item,
[Queue("outputQueue")]
CloudQueue outputQueue,
DateTimeOffset nextVisibleTime,
DateTimeOffset expirationTime,
DateTimeOffset insertionTime,
ILogger log)
{
log.LogInformation("########## Function 1 ###############");
log.LogInformation($"NextVisibleTime: {nextVisibleTime}");
log.LogInformation($"NextVisibleTime: {(nextVisibleTime-insertionTime).TotalSeconds}");
log.LogInformation($"C# Queue trigger function processed: {item.AsString}");
Thread.Sleep(TimeSpan.FromMinutes(20));
}
[FunctionName("WorkerFunction2")]
public static async Task Function2(
[QueueTrigger("outputQueue")]
CloudQueueMessage item,
[Queue("outputQueue")]
CloudQueue outputQueue,
DateTimeOffset nextVisibleTime,
DateTimeOffset expirationTime,
DateTimeOffset insertionTime,
ILogger log)
{
log.LogInformation("########## Function 2 ###############");
log.LogInformation($"NextVisibleTime: {nextVisibleTime}");
log.LogInformation($"NextVisibleTime: {(nextVisibleTime - insertionTime).TotalSeconds}");
log.LogInformation($"C# Queue trigger function processed: {item.AsString}");
Thread.Sleep(TimeSpan.FromMinutes(20));
}
}
}
有了这个主机文件
{
"version": "2.0",
"extensions": {
"queues": {
"maxPollingInterval": "00:00:02",
"visibilityTimeout": "00:00:10",
"batchSize": 16,
"maxDequeueCount": 5,
"newBatchThreshold": 8
}
}
}
当我将一条简单消息放入队列并让它 运行 时,我看到以下内容:
- 抓住它的函数,在睡眠结束前不会释放它
- 我在日志中看不到租约已续订,但它似乎是在幕后发生的
这告诉我什么:
- 如果函数没有失败,或者主机没有失败,那么租约将根据以下条件自动续订:
- 当达到可见性超时且函数为 运行ning 时,消息不会 "readded" 进入队列
- 关于 visibilityTimeout 的文档是真实的:"The time interval between retries when processing of a message fails."(来自 https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue#hostjson-settings)
我没有保存任何与此相矛盾的 3.party 链接(抱歉,我没有保存这些链接),但它们存在。我希望有人能回答这个问题,这样我就可以得到澄清。
这里似乎实际上使用了两个不同的可见性超时值。两者都由 Azure WebJobs SDK 设置,但只有一个是可配置的。
当函数失败时
queues.visibilityTimeout
配置选项更恰当地命名为 retryDelay
。
当函数抛出异常或因其他类型的错误而失败时,消息将返回到队列中以供重试。该消息与配置的 visibilityTimeout
(参见 here)一起返回,这会延迟函数下一次尝试 运行.
这使您的应用程序能够处理暂时性错误。例如,如果电子邮件 API 或其他外部服务暂时关闭。通过延迟重试,服务有可能重新联机以进行下一次功能尝试。
重试限制为 maxDequeueCount
次尝试(默认为 5 次),然后将消息移至 Poison Queue。
虽然函数是运行宁
当 QueueTrigger
绑定 运行 函数时,它将消息出列,可见性超时为 10 分钟(hard-coded here). It then sets a timer to extend the visibility window when it reaches half-time as long as the function is running (see the timer and visibility update 在源中)。
通常您不需要担心这个,只要您的函数正确使用 CancellationToken
s 即可。仅当 Azure Function/WebJob 主机没有到达 shut down gracefully 时,这 10 分钟的超时才有意义。例如:
- 有人在虚拟主机上“拔掉插头”
- 如果函数在 scale-in or other Azure shutdown events 期间没有及时响应
CancellationToken
因此,只要函数仍然是 运行ning,消息就会在队列中保持隐藏状态。
验证
我做了一个类似的实验来检查:
[FunctionName("SlowJob")]
public async Task Run(
[QueueTrigger("slow-job-queue")] CloudQueueMessage message,
ILogger log)
{
for (var i = 0; i < 20; i++)
{
log.LogInformation($"Next visible {i}: {message.NextVisibleTime}");
await Task.Delay(60000);
}
}
输出:
Next visible 0: 5/11/2020 7:49:24 +00:00
Next visible 1: 5/11/2020 7:49:24 +00:00
Next visible 2: 5/11/2020 7:49:24 +00:00
Next visible 3: 5/11/2020 7:49:24 +00:00
Next visible 4: 5/11/2020 7:49:24 +00:00
Next visible 5: 5/11/2020 7:54:24 +00:00
Next visible 6: 5/11/2020 7:54:24 +00:00
Next visible 7: 5/11/2020 7:54:24 +00:00
Next visible 8: 5/11/2020 7:54:24 +00:00
Next visible 9: 5/11/2020 7:54:24 +00:00
Next visible 10: 5/11/2020 7:59:24 +00:00
Next visible 11: 5/11/2020 7:59:24 +00:00
...