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已过时了吗?在参考资料中找不到它。)
答案 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}");
}
}}