计划的 WebJob 长时间运行时会发生什么

What happens when a scheduled WebJob runs for a long time

如果 Azure WebJob 计划 运行 但前一个 运行ning 实例尚未完成,会发生什么情况?它会再次 运行 WebJob 以便两个同时 运行ning 吗?它不会 运行 WebJob 并重新开始吗?我无法在任何地方找到这种行为的记录。我有一份工作,我想 运行 每小时完成一次,但有时可能需要一个多小时才能完成,但我不想同时完成其中两个 运行。

据我了解,计划的 webjobs 只是使用 Azure Scheduler 运行 触发的 webjobs,如果您在管理门户中打开 Azure Scheduler,您可以看到 webjobs,甚至可以更详细地配置它们。 (你也可以看到日志,它会给你问题的简单答案)。

如果您想查看计划的 webjob 是 运行 作为 Kudu 触发的 webjob,如果您查看 Kudu 源代码,您会看到在作业启动时创建了一个锁定文件,如果您尝试启动另一个 job a ConflictException is thrown if there is already a lock file

Azure 调度程序使用 catches the ConflictException and gives you the "Error_WebJobAlreadyRunning" warning 的 webhook 调用你的作业,它会告诉你:"Cannot start a new run since job is already running."

我发现限制 WebJob 执行的最佳方法是使用计划的 WebJob 使用内置队列对要完成的工作进行排队,然后创建一个连续运行的单独 WebJob,只要有新的队列消息就会执行出现但设置 BatchSize = 1。这有效地防止了任何作业并发执行。

下面是 WebJob 中用于排队消息的一些示例代码。

class Program
{
  static void Main()
  {
    var host = new JobHost();
    host.Call(typeof(Functions).GetMethod("QueueSomething"));
  }
}
public class Functions
{
  [NoAutomaticTrigger]
  public static void QueueSomething([Queue("myqueue")] ICollector<string> message, TextWriter log)
  {
    //do some work here to create a message to pass to the other WebJob so it can execute your task
    string x = "serialize some data or instructions to pass";
    
    //if I want to pass it a couple of things to do use ICollector above and add this to the queue too
    string x2 = "some additional task to do";
    

  //Add the json to the WebJobs queue
  message.Add(x);
  message.Add(x2);
}

这是连续 运行 WebJob 中的代码。这会监视 "myqueue",然后在出现新消息时调用 DoSomething()。关键是 BatchSize 属性 阻止此 WebJob 读取和处理另一条消息,直到第一条消息完成。

class Program
{
    static void Main()
    {
        JobHostConfiguration config = new JobHostConfiguration();

        //Read and process one message at a time
        config.Queues.BatchSize = 1;
        var host = new JobHost(config);
        host.RunAndBlock();
    }
}

public class Functions
{
    public static void DoSomething([QueueTrigger("myqueue")] string message, TextWriter log)
    {
     //Read and deserialize your message and then do some work with it
     string d = JsonConvert.DeserializeObject(message);
    }
}

希望对您有所帮助。