【问题标题】:Azure BlobTrigger is firing > 5 times for each new blobAzure BlobTrigger 为每个新 blob 触发 > 5 次
【发布时间】:2019-11-22 02:53:42
【问题描述】:

在将 blob(图像)上传到 Azure 存储后,以下触发器会从它们中删除 exif 数据。问题是每个 blob 的 blob 触发器至少触发 5 次。

在触发器中,通过向 Blob 写入新的数据流来更新 Blob。我曾假设blob receipts 会阻止对该blob 进一步触发blob 触发器。

[FunctionName("ExifDataPurge")]
public async System.Threading.Tasks.Task RunAsync(
    [BlobTrigger("container/{name}.{extension}", Connection = "")]CloudBlockBlob image,
    string name,
    string extension,
    string blobTrigger,
    ILogger log)
{
    log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name}");

    try
    {
        var memoryStream = new MemoryStream();
        await image.DownloadToStreamAsync(memoryStream);
        memoryStream.Position = 0;
        using (Image largeImage = Image.Load(memoryStream))
        {
            if (largeImage.Metadata.ExifProfile != null)
            {
                //strip the exif data from the image. 
                for (int i = 0; i < largeImage.Metadata.ExifProfile.Values.Count; i++)
                {
                    largeImage.Metadata.ExifProfile.RemoveValue(largeImage.Metadata.ExifProfile.Values[i].Tag);
                }

                var exifStrippedImage = new MemoryStream();
                largeImage.Save(exifStrippedImage, new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder());
                exifStrippedImage.Position = 0;

                await image.UploadFromStreamAsync(exifStrippedImage);
            }
        }
    }
    catch (UnknownImageFormatException unknownImageFormatException)
    {
        log.LogInformation($"Blob is not a valid Image : {name}.{extension}");
    }
}

【问题讨论】:

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


【解决方案1】:

触发器的处理方式是通过将收据存储在容器 azure-webjobs-hosts 中来跟踪哪些 blob 已被处理。任何没有收据的 blob 或旧收据(基于 blob ETag)都将被处理(或重新处理)。

因为你正在调用 await image.UploadFromStreamAsync(exifStrippedImage); 它被触发(假设它没有被处理)

【讨论】:

  • 您是说如果我将新数据上传到现有 blob 中,ETag 会发生变化?
【解决方案2】:

当你调用await image.UploadFromStreamAsync(exifStrippedImage);时,它会更新blob,所以blob函数会再次触发。

您可以尝试检查 blob 上现有的 CacheControl 属性,如果它已被更新以中断循环,则不要更新它。

// Set the CacheControl property to expire in 1 hour (3600 seconds)
blob.Properties.CacheControl = "max-age=3600";

【讨论】:

    【解决方案3】:

    因此,我通过在处理 blob 时将状态存储在元数据中来解决此问题。

    https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-container-properties-metadata

    然后触发器包含一个检查元数据的警卫。

    if (image.Metadata.ContainsKey("Status") && image.Metadata["Status"] == "Processed")
    {
        //an subsequent processing for the blob will enter this block. 
        log.LogInformation($"blob: {name} has already been processed");
    }
    else
    {
         //first time triggered for this blob
         image.Metadata.Add("Status", "Processed");
         await image.SetMetadataAsync();
    }
    

    其他答案为我指明了正确的方向。我认为使用元数据更正确。当我们可以存储元数据时,将 ETag 存储在其他地方似乎是多余的。使用“CacheControl”似乎太过分了,其他开发人员可能会对我这样做的内容和原因感到困惑。

    【讨论】:

      猜你喜欢
      • 2019-10-23
      • 2022-07-07
      • 1970-01-01
      • 2019-12-17
      • 2021-03-19
      • 1970-01-01
      • 2019-02-15
      • 2021-05-27
      • 2021-02-26
      相关资源
      最近更新 更多