Azure 函数主机与 OutOfMemoryException 一起死亡,而不会触发



快速版本:为什么我的函数主机在 5 分钟后什么都不做就自己杀死了?

我有一个 Azure 函数,它使用 nClam 扫描 blob 文件中的病毒。它似乎工作得很好,但突然间它会在触发任何斑点之前自行杀死它!它将在 5 分钟后关闭,并显示内存不足异常:

[18/9/2019 10:33:33] Host initialized (405ms)
[18/9/2019 10:33:33] Host started (812ms)
[18/9/2019 10:33:33] Job host started
Hosting environment: Production
Content root path: D:gitTopoAPIAntivirusbinDebugnetcoreapp2.1
Now listening on: http://0.0.0.0:7071
Application started. Press Ctrl+C to shut down.
[18/9/2019 10:33:38] Host lock lease acquired by instance ID '000000000000000000000000C913FBA0'.
[18/9/2019 10:38:46] An unhandled exception has occurred. Host is shutting down.
[18/9/2019 10:38:46] Microsoft.WindowsAzure.Storage: Exception of type 'System.OutOfMemoryException' was thrown. System.Private.CoreLib: Exception of type 'System.OutOfMemoryException' was thrown.
[18/9/2019 10:38:46] Stopping host...
[18/9/2019 10:38:46] Stopping JobHost
[18/9/2019 10:38:46] Job host stopped
[18/9/2019 10:38:46] Host shutdown completed.
Application is shutting down...

下面是我的扫描斑点触发函数:

[FunctionName("scanImports")]
public static async Task Scan([BlobTrigger("imports/{newBlobName}", Connection = "BlobConnectionstring")]CloudBlockBlob newBlob, string newBlobName, ILogger log, ExecutionContext context)
{
var config = new ConfigurationBuilder().SetBasePath(context.FunctionAppDirectory).AddJsonFile("local.settings.json", optional: true, reloadOnChange: true).AddEnvironmentVariables().Build();
var clamClient = new ClamClient(config["ContainerAddress"], int.Parse(config["ContainerPort"]));
var blobFileStream = await newBlob.OpenReadAsync();
using (var memoryStream = new MemoryStream())
{
await blobFileStream.CopyToAsync(memoryStream);
var result = await clamClient.SendAndScanFileAsync(memoryStream.ToArray());
bool isClean = result.InfectedFiles == null || result.InfectedFiles.Count == 0;
// Check if newBlob is infected. If infected, move to quarantineBlob
if (!isClean)
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(config["blobConnectionstring"]);
CloudBlobClient client;
CloudBlobContainer container;
CloudBlockBlob quarantineBlob;
client = storageAccount.CreateCloudBlobClient();
container = client.GetContainerReference(config["QuarantineBlobName"]);
await container.CreateIfNotExistsAsync();
quarantineBlob = container.GetBlockBlobReference(newBlobName);
quarantineBlob.Properties.ContentType = newBlob.Properties.ContentType;
await quarantineBlob.UploadFromStreamAsync(memoryStream);
await newBlob.DeleteAsync();
}
}
}

更新 1:主机在整整 5 分钟后死亡,并出现内存不足异常。我试图延长函数超时,这没有什么区别。 在此期间,进程将不断使用 5-8% 的 CPU,并且在它死亡之前,进程将使用超过 1500 MB 的内存。

更新 2:如果我从函数中删除所有代码,只留下一个 log.info(( 语句,主机在 5 分钟后仍然会自行杀死它,并出现 OutOfMemoryException

我问题的原因是我尝试触发的 blob 中有 100.000+ 个文件。Microsoft将其定义为"大规模"。

所以我的代码实际上没有问题。只是如果我尝试在"大规模"blob 上触发,那么我的代码将什么都不做,只是分配内存并死亡。

默认情况下,Azure 函数的生存期为 5 分钟。在那之后,它会自杀。

如果在应用服务计划上托管 azure 函数,则可以在 host.json 中将functionTimeout值设置为更高的值

指示所有函数的超时持续时间。

在无服务器消耗计划中,有效范围为 1 秒到 10 分钟,默认值为 5 分钟。

在应用服务计划中,没有总体限制,默认值取决于运行时版本。

在版本 2.x 中,应用服务计划的默认值为 30 分钟。

在版本 1.x 中,它为 null,表示没有超时。它不能设置为无限。 如果我们没有明确设置此值,它将采用默认的 30 分钟值。

https://learn.microsoft.com/en-us/azure/azure-functions/functions-host-json#functiontimeout

最新更新