使用 TimerTrigger 对连续作业使用 Azure WebJob 超时
Using Azure WebJob Timeout on Continuous Job with TimerTrigger
我有一个连续的 WebJob,其功能使用 TimerTrigger 运行 每 30 秒一个进程。该函数中的某个特定调用偶尔且看似随机挂起,导致 Web 作业无限期等待。当前的解决方案是注意到服务已停止,然后登录到 Azure 仪表板并手动中止它。
请注意,我知道正确的做法是找出根本原因并加以解决。相信我,我们正在努力。同时,我想治标,需要帮助
我正在尝试让 WebJob 检测是否使用 Timeout 装饰器的状态,如 Azure WebJobs SDK post 中所述:https://github.com/Azure/azure-webjobs-sdk/issues/590。实施该建议后,我可以看到当有问题的调用挂起时,会检测到超时,但 WebJob 仍未终止 。我在这里做错了什么不会终止函数以允许后续调用?
Program.cs
static void Main()
{
var config = new JobHostConfiguration();
config.UseTimers();
config.FunctionTimeout = new TimeSpan(0, 15, 0);
var host = new JobHost(config);
Functions.Initialize();
host.RunAndBlock();
}
Functions.cs
[Singleton]
[Timeout("00:05:00")]
public async static Task PeriodicProcess([TimerTrigger("00:00:30", RunOnStartup = true)] TimerInfo timer, CancellationToken cancelToken, TextWriter log)
{
log.WriteLine("-- Processing Begin --");
List<Emails> cases = GetEmailsAndWhatNot();
foreach (Email e in Emails)
{
try
{
ProblematicFunction_SendEmail(e, log);
}
catch(Exception e)
{
// do stuff
}
}
log.WriteLine("-- Processing End -- ");
}
public static void ProblematicFunction_SendEmail(Email e, TextWriter log)
{
// send email
}
问题期间的 WebJob 输出
-- Processing Begin --
Timeout value of 00:05:00 exceeded by function 'Functions.PeriodicProcess' (Id: '0f7438bd-baad-451f-95a6-9461f35bfb2d'). Initiating cancellation.
尽管 webjob 启动了取消,但函数并没有消失。我需要监控 CancellationToken 吗?我需要向下传播多远的异步调用?我在这里错过了什么实际上会中止这个过程?
正如 TimerTrigger 关于 TimerTrigger 的陈述:
单例锁
TimerTrigger uses the Singleton feature of the WebJobs SDK to ensure that only a single instance of your triggered function is running at any given time.
计划
If your function execution takes longer than the timer interval, another execution won't be triggered until after the current invocation completes. The next execution is scheduled after the current execution completes.
这是我对这个场景的测试,你可以参考一下:
使用CancellationToken.None
并且从不传播取消令牌
注意:函数PeriodicProcess
会在30秒后超时,但耗时作业仍然是运行,经过很长时间-运行作业完成,将打印Processing End日志。
传播取消令牌
注意:如果我们传播取消令牌,耗时作业将立即被取消。
代码片段
[Timeout("00:00:30")]
[Singleton]
public async static Task PeriodicProcess([TimerTrigger("00:00:10", RunOnStartup = true)] TimerInfo timer, CancellationToken cancelToken, TextWriter log)
{
log.WriteLine($"-- [{DateTime.Now.ToString()}] Processing Begin --");
try
{
await longRunningJob(log, cancelToken);
}
catch (Exception e)
{
// do stuff
}
log.WriteLine($"-- [{DateTime.Now.ToString()}] Processing End -- ");
}
private async static Task longRunningJob(TextWriter log, CancellationToken cancelToken)
{
log.WriteLine($"-- [{DateTime.Now.ToString()}] Begin Time-consuming jobs --");
await Task.Delay(TimeSpan.FromMinutes(1), cancelToken);
log.WriteLine($"-- [{DateTime.Now.ToString()}] Complete Time-consuming jobs --");
}
我有一个连续的 WebJob,其功能使用 TimerTrigger 运行 每 30 秒一个进程。该函数中的某个特定调用偶尔且看似随机挂起,导致 Web 作业无限期等待。当前的解决方案是注意到服务已停止,然后登录到 Azure 仪表板并手动中止它。
请注意,我知道正确的做法是找出根本原因并加以解决。相信我,我们正在努力。同时,我想治标,需要帮助
我正在尝试让 WebJob 检测是否使用 Timeout 装饰器的状态,如 Azure WebJobs SDK post 中所述:https://github.com/Azure/azure-webjobs-sdk/issues/590。实施该建议后,我可以看到当有问题的调用挂起时,会检测到超时,但 WebJob 仍未终止 。我在这里做错了什么不会终止函数以允许后续调用?
Program.cs
static void Main()
{
var config = new JobHostConfiguration();
config.UseTimers();
config.FunctionTimeout = new TimeSpan(0, 15, 0);
var host = new JobHost(config);
Functions.Initialize();
host.RunAndBlock();
}
Functions.cs
[Singleton]
[Timeout("00:05:00")]
public async static Task PeriodicProcess([TimerTrigger("00:00:30", RunOnStartup = true)] TimerInfo timer, CancellationToken cancelToken, TextWriter log)
{
log.WriteLine("-- Processing Begin --");
List<Emails> cases = GetEmailsAndWhatNot();
foreach (Email e in Emails)
{
try
{
ProblematicFunction_SendEmail(e, log);
}
catch(Exception e)
{
// do stuff
}
}
log.WriteLine("-- Processing End -- ");
}
public static void ProblematicFunction_SendEmail(Email e, TextWriter log)
{
// send email
}
问题期间的 WebJob 输出
-- Processing Begin --
Timeout value of 00:05:00 exceeded by function 'Functions.PeriodicProcess' (Id: '0f7438bd-baad-451f-95a6-9461f35bfb2d'). Initiating cancellation.
尽管 webjob 启动了取消,但函数并没有消失。我需要监控 CancellationToken 吗?我需要向下传播多远的异步调用?我在这里错过了什么实际上会中止这个过程?
正如 TimerTrigger 关于 TimerTrigger 的陈述:
单例锁
TimerTrigger uses the Singleton feature of the WebJobs SDK to ensure that only a single instance of your triggered function is running at any given time.
计划
If your function execution takes longer than the timer interval, another execution won't be triggered until after the current invocation completes. The next execution is scheduled after the current execution completes.
这是我对这个场景的测试,你可以参考一下:
使用
CancellationToken.None
并且从不传播取消令牌注意:函数
PeriodicProcess
会在30秒后超时,但耗时作业仍然是运行,经过很长时间-运行作业完成,将打印Processing End日志。传播取消令牌
注意:如果我们传播取消令牌,耗时作业将立即被取消。
代码片段
[Timeout("00:00:30")]
[Singleton]
public async static Task PeriodicProcess([TimerTrigger("00:00:10", RunOnStartup = true)] TimerInfo timer, CancellationToken cancelToken, TextWriter log)
{
log.WriteLine($"-- [{DateTime.Now.ToString()}] Processing Begin --");
try
{
await longRunningJob(log, cancelToken);
}
catch (Exception e)
{
// do stuff
}
log.WriteLine($"-- [{DateTime.Now.ToString()}] Processing End -- ");
}
private async static Task longRunningJob(TextWriter log, CancellationToken cancelToken)
{
log.WriteLine($"-- [{DateTime.Now.ToString()}] Begin Time-consuming jobs --");
await Task.Delay(TimeSpan.FromMinutes(1), cancelToken);
log.WriteLine($"-- [{DateTime.Now.ToString()}] Complete Time-consuming jobs --");
}