如何“欺骗” Azure Function运行超过10分钟

时间:2018-07-14 21:50:57

标签: c# azure azure-functions azure-blob-storage

Azure功能的时限为10分钟。假设我有一个长期运行的任务,例如下载需要1个小时才能下载的文件。

[FunctionName("PerformDownload")]
[return: Queue("download-path-queue")]
public static async Task<string> RunAsync([QueueTrigger("download-url-queue")] string url, TraceWriter log)
{
   string downloadPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString);
   log.Info($"Downloading file at url {url} to {downloadPath} ...");
   using (var client = new WebClient())
   {
       await client.DownloadFileAsync(new Uri(url), myLocalFilePath);
   }
   log.Info("Finished!");   
}

是否有任何骇人听闻的方法来使类似的事情开始,然后在时限到期之前在另一个功能中恢复?还是有一种更好的方法将诸如此类的长任务集成到使用Azure Functions的工作流中?

(在一个稍微相关的注释上,简单的Azure Web Jobs已过时了吗?在参考资料中找不到它。)

5 个答案:

答案 0 :(得分:3)

  

是否有任何骇人听闻的方法可以使类似的事情开始,然后   在时限到期之前恢复其他功能?

如果您使用的是消费计划,则无法控制Function App的运行时间,因此,使用在Function入口点完成后继续运行的后台线程是不可靠的。

在App Service计划上,您要在要付费的VM上运行,因此可以将Function App配置为连续运行。另外,您也不必在App Service计划上设置功能超时,因此您的主要功能入口点可以运行任意长时间。

  

或者是否有更好的方法将诸如此类的长任务集成到使用Azure Functions的工作流中?

是的。使用Azure Data Factory将数据复制到Blob存储中,然后进行处理。数据工厂管道可以在复制活动之前和之后调用函数。

答案 1 :(得分:3)

为可能遇到此帖子的其他人添加一个内容:可以使用Durable Functions扩展名在代码中创建由多个Azure函数组成的工作流,该扩展名可用于创建编排函数以安排异步任务,关闭和异步工作完成后,系统会重新唤醒。

对于需要打开TCP端口的长时间运行的任务(例如下载文件)(为此,在App Service Plan上运行的功能没有执行时间限制),它们不是直接的解决方案,但是可以用于将此类任务集成到更大的工作流程中。

答案 2 :(得分:2)

取决于工作负载的详细信息,另一种选择是利用Azure容器实例。您可以让Azure函数启动一个容器,处理您的工作量(下载文件\做一些处理等),然后为您关闭容器。加速时间通常为几秒钟,您只需为使用的东西付费(不需要专用的应用程序服务计划或虚拟机实例)。有关ACI here的更多详细信息。

答案 3 :(得分:0)

触发功能应用程序的最后一个功能后,

10分钟(基于host.json文件中的超时设置),运行功能应用程序的VM将停止。

为防止发生这种情况,您可以每5分钟运行一个空的Timertrigger function。它不会花费任何费用,并且可以保持您的应用程序正常运行。

答案 4 :(得分:0)

我认为该问题与冷启动状态有关。在这里您可以找到有关它的更多详细信息。 https://markheath.net/post/avoiding-azure-functions-cold-starts

您可以做的是,创建一个触发azure函数,以“ ping”您长时间运行的函数以使其保持“温暖”

namespace NewProject
{
 public static class PingTimer
    {
        [FunctionName("PingTimer")]
        public static async Task Run([TimerTrigger("0 */4 * * * *")]TimerInfo myTimer, TraceWriter log)
        {
            // This CRON job executes every 4 minutes

log.Info($"PingTimer function executed at: {DateTime.Now}");

            var client = new HttpClient();
            string url = @"<Azure function URL>";
            var result = await client.GetAsync(new Uri(url));

            log.Info($"PingTimer function executed completed at: {DateTime.Now}");
        }
    }}