连续 Azure WebJob 何时停止 NoAutomaticTrigger 类型作业的通知

Notification of when continuous Azure WebJob is stopping for NoAutomaticTrigger type jobs

全部,

我正在将现有的辅助角色代码迁移到 Azure Web 作业。我正在尝试使用 WebJob SDK (1.0),以便与 Azure 网站完全集成。

我的困难是 JobHost 不能很好地处理它通常基于属性的调用选项(队列、Blob 等)之外的作业

我已经有标准代码,我无法更改以收听 Azure Queues/Topics 等,因此我无法使用 WebJob 代码来执行此操作。

因此我需要使用 WebJob Call 方法:

var cancelTokenSource = new CancellationTokenSource();
var onStartMethod = typeof(Program).GetMethod("OnStart", BindingFlags.Static | BindingFlags.Public);

host.CallAsync(onStartMethod, cancelTokenSource.Token)
    .ConfigureAwait(false)
    .GetAwaiter()
    .GetResult();

注意:我正在使用自己的 CallAsync,因为所有建议都是在使用库时使用 ConfigureAwait(false) 但 JobHost 的内部结构不这样做,所以我正在复制它的 "call" 代码我自己,但使用 ConfigureAwait。据我所知,取消令牌在 JobHost 中没有任何作用。

我的问题是我需要调用 host.RunAndBlock();停止作业退出,这很好,但是我需要运行一些清理处理。我无法使用 OnStop 方法对 "CallAsync" 进行新调用,因为 Host 已被取消,所以我所能做的就是直接调用我的 OnStop 方法。不幸的是,我失去了通过提供的 TextWriter class.

写入网站日志的能力

我认为我需要一种方法让 JobHost 在 RunAndBlock 中调用我的方法,这样我就可以获取主机关闭时触发的取消令牌,然后执行我的清理代码....但是似乎没有办法做到这一点。

我有没有明显的遗漏? JobHost 似乎真的很不擅长处理超出常态的场景:(

NB: I am using my own CallAsync as all the advice is to use ConfigureAwait(false) when using libraries but the innards of JobHost doesn't do this, so I'm replicating it's "call" code myself but with the ConfigureAwait. The cancellation token doesn't do anything in JobHost as far as I can tell.

这是预料之中的,因为您传递的是您自己的取消令牌,该令牌未被任何人取消。当 shutdown notification is sent 或主机为 stopped/disposed 时,将取消 webjobs 取消标记。如果您想从网络作业函数外部获取对取消令牌的引用,则必须将其保存在静态变量或类似变量中。

如果您想使用自己的取消令牌,您可以使用 Microsoft.Azure.WebJobs.WebJobsShutdownWatcher 来获取关闭通知。

My problem is that I then need to call host.RunAndBlock(); to stop the job exiting, which is fine, but then I need to run some clean up processing. I can't make a new call to "CallAsync" with an OnStop method, as the Host is already being cancelled, so all I can do is make a direct call to my OnStop method. Unfortunately then I lose the ability to write to the WebSite log through the provided TextWriter class.

对此没有开箱即用的解决方案,但您可以从 运行 网络作业(如果有)调用清理功能。如果您需要在函数之外进行清理并且还需要日志记录,那么您只能进行控制台日志记录 - 写入控制台。日志将显示在 WebJobs 仪表板上的 webJob 页面上。我很好奇,如果您需要在函数之外进行清理,情况会怎样?

正如维克多所说,您可以使用 Microsoft.Azure.WebJobs.WebJobsShutdownWatcher
这是 Amit 解决方案的实现:WebJobs Graceful Shutdown

所以我找到了一个解决方案:
Program.cs

中没有修改
class Program
{
    static void Main()
    {
        var host = new JobHost();
        host.Call(typeof(Startup).GetMethod("Start"));
        host.RunAndBlock();
    }
}

正常关机进入 Startup.cs :

public class Startup
{
    [NoAutomaticTrigger]
    public static void Start(TextWriter log)
    {
        var token = new Microsoft.Azure.WebJobs.WebJobsShutdownWatcher().Token;
        //Shut down gracefully
        while (!token.IsCancellationRequested)
        {
            // Do somethings
        }
    }
}

while 循环后,您还可以停止已启动的任务。