重新部署网站时,连续 Azure WebJob 上的 运行 进程会发生什么情况?

What happens to running processes on a continuous Azure WebJob when website is redeployed?

我读过关于使用取消令牌的正常关闭 here using the WEBJOBS_SHUTDOWN_FILE and here,所以我理解正常关闭的前提,但是我不确定它们将如何影响正在处理队列的 WebJobs留言。

场景是这样的:

  1. 我有一个具有监听队列功能的 WebJob。
  2. 消息添加到队列中,作业开始处理。
  3. 处理的时候,有人推送开发,触发重新部署。

假设我已连接我的 WebJobs 以在 git 推送时进行部署,此部署还将触发要更新的 WebJobs,这(据我所知)将启动某种关闭工作流工作。所以我有几个问题。

  1. 正在处理队列消息的作业是否会在作业退出之前完成对消息的处理?或者任何关机通知本质上都被视为 "this bitch is about to shutdown. If you don't have anything to handle it, you're SOL."
  2. 如果我们是 SOL,我们处理关闭的最佳选择是否本质上是将您正在做的任何事情包装在相当于数据库事务中,并以所有更改在关闭时回滚的方式实现您的关闭处理程序?
  3. 如果队列消息正在处理过程中并且 WebJob 关闭,该消息是否会重新排队?如果不是,是否意味着我的关闭处理程序需要处理重新排队该消息?
  4. Job 收到需要关闭的通知后,侦听队列的函数是否可以获取更多队列消息?

非常感谢这里的任何指导!此外,如果除了我提到的那些之外,还有任何其他关于如何处理作业关闭的有用链接,如果你能分享这些链接就太好了。

经过大量测试,我想我已经找到了问题的答案,希望其他人可以从我的经验中获得一些见解。

注意:所有这些场景都使用 .NET 控制台应用程序和 Azure 队列进行了测试,所以我不确定 blob 或 table 存储或不同类型的作业文件类型如何处理这些不同的场景。

  1. 作业被标记为退出后,运行 触发的函数将具有配置的时间量(宽限期)(默认为 5 秒,但我认为是 configurable by using a settings.job file) 在它们退出之前完成。如果他们没有在宽限期内完成,函数将退出。但是,Main()(或您在其中声明 host.RunAndBlock() 的任何文件)将完成 运行 在 host.RunAndBlock() 之后的任何代码,直到宽限期剩余的时间(我如果您使用无限循环而不是 RunAndBlock,我不确定它会如何工作)。至于处理函数中的退出,您基本上可以 "listen" 到 CancellationToken,您可以将其传递给 IsCancellationRequired 的触发函数,然后相应地处理它。此外,如果您不自己处理退出,您就不是 SOL。万岁!参见第 3 点。

  2. 虽然如果你不处理退出就不是 SOL(见第 3 点),但我确实认为将你所有的工作包装在 t运行 在您完全确定工作已完成 运行 之前,您不会提交的操作。这样,如果您的函数在进程中退出,您就不太可能担心数据损坏。我可以想到几个场景,您可能希望在 t运行sactions 通过时提交它们(例如,批处理作业),但是您需要构建数据或逻辑,以便不会重新处理以前处理过的实体作业重启后。

  3. 如果您不自己处理辞职,您就不会遇到麻烦。我几乎不了解幕后发生的事情,但我对结果非常确定。如果一个函数正在处理队列消息并且在它完成之前被迫退出,请不要害怕!当作业抓取要处理的消息时,它实际上会将消息隐藏在队列中一段时间​​。如果您的函数在处理消息时退出,该消息将在 x 时间后再次 "become visible",并且将被重新抓取并 运行 针对刚刚部署的可能更新的代码。

  4. 所以我对#4 的发现有大约 90% 的信心。我之所以这么说,是因为尝试测试它涉及在 windows 之间快速切换,而实际上并不完全确定某些片段发生了什么。但这是我发现的:如果队列在宽限期 b4 中添加了新消息,则作业退出,我认为可能会发生以下两种情况之一:如果函数在作业之前没有轮询该队列退出,然后消息将保留在队列中,并在作业重新启动时被抓取。但是,如果该函数确实获取了该消息,它将与被中断的任何其他消息一样被对待:它将再次 "become visible" 在队列中并在作业重新启动时重新 运行。

总结得差不多了。我希望其他人会发现这很有用。让我知道您是否想要详细说明这些内容,我很乐意尝试。或者,如果我满载而你有很多更正,这些可能更受欢迎!