我有一个连续的WebJob,其函数使用TimerTrigger每30秒运行一个进程。函数中的特定调用偶尔会看似随机挂起,导致webjob无限期地等待。当前解决方案注意到服务已停止,然后登录Azure仪表板并手动中止。
请注意,我知道正确的操作方法是确定根本原因并进行修复。相信我,我们正在努力。与此同时,我想治疗症状,并需要帮助。
我试图让WebJob使用Timeout装饰器检测状态,如Azure WebJobs SDK上的这篇文章所述:https://github.com/Azure/azure-webjobs-sdk/issues/590。实施该建议后,我能够看到当有问题的呼叫挂断时,会检测到超时,但 WebJob仍然没有死亡。我在这里做错了什么不会杀死函数以允许后续的调用?
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();
}
[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
}
- 处理开始 -
00:05:00的超时值超出功能&#39; Functions.PeriodicProcess&#39; (Id:&#39; 0f7438bd-baad-451f-95a6-9461f35bfb2d&#39;)。开始取消。
尽管webjob启动取消,但功能并没有消失。我是否需要监控CancellationToken?我需要在多长时间内传播异步调用?我在这里错过了什么会实际中止这个过程?
答案 0 :(得分:2)
正如TimerTrigger所述有关TimerTrigger的信息:
Singleton Locks
TimerTrigger使用WebJobs SDK的 Singleton 功能,确保在任何给定时间只有单个触发函数实例。
计划强>
如果函数执行时间超过计时器间隔,则在当前调用完成后才会触发另一次执行。在当前执行完成后安排下一次执行。
以下是我对此方案的测试,您可以参考它:
使用CancellationToken.None
并且永远不会传播取消令牌
注意:函数PeriodicProcess
将在30秒后超时,但耗时的作业仍在运行,并且在长时间运行的作业完成后,处理结束将打印日志。
宣传取消令牌
注意:如果我们传播取消令牌,则会立即取消耗时的工作。
代码段
[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 --");
}