适用于 Azure Functions 的 Azure Blob 存储触发器Azure Blob storage trigger for Azure Functions

检测到新的或更新的 Blob 时,Blob 存储触发器会启动某个函数。The Blob storage trigger starts a function when a new or updated blob is detected. Blob 内容以函数输入的形式提供。The blob contents are provided as input to the function.

Azure Blob 存储触发器需要使用常规用途存储帐户。The Azure Blob storage trigger requires a general-purpose storage account. 还支持具有分层命名空间的存储 V2 帐户。Storage V2 accounts with hierarchal namespaces are also supported. 若要使用仅限 Blob 的帐户,或者,如果应用程序有特殊需求,请查看使用此触发器的替代方法。To use a blob-only account, or if your application has specialized needs, review the alternatives to using this trigger.

若要了解设置和配置详细信息,请参阅概述For information on setup and configuration details, see the overview.

备选方法Alternatives

事件网格触发器Event Grid trigger

事件网格触发器还为 blob 事件提供内置支持。The Event Grid trigger also has built-in support for blob events. 以下方案请使用事件网格而不是 Blob 存储触发器:Use Event Grid instead of the Blob storage trigger for the following scenarios:

  • 仅限 Blob 的存储帐户仅限 Blob 的存储帐户适用于 Blob 输入和输出绑定,但不适用于 Blob 触发器。Blob-only storage accounts: Blob-only storage accounts are supported for blob input and output bindings but not for blob triggers.

  • 大规模:大规模可以宽松地定义为包含 100,000 个以上的 Blob 的容器,或者定义为每秒进行 100 个以上 Blob 更新的存储帐户。High-scale: High scale can be loosely defined as containers that have more than 100,000 blobs in them or storage accounts that have more than 100 blob updates per second.

  • 最大程度地降低延迟:如果函数应用基于消耗计划,则当函数应用处于空闲状态时,处理新 Blob 会出现长达 10 分钟的延迟。Minimizing latency: If your function app is on the Consumption plan, there can be up to a 10-minute delay in processing new blobs if a function app has gone idle. 若要避免此延迟,可以切换到启用了 Always On 的应用服务计划。To avoid this latency, you can switch to an App Service plan with Always On enabled. 还可以为 Blob 存储帐户使用事件网格触发器You can also use an Event Grid trigger with your Blob storage account. 有关示例,请参阅事件网格教程For an example, see the Event Grid tutorial.

请参阅事件网格示例的使用事件网格重试图像大小教程。See the Image resize with Event Grid tutorial of an Event Grid example.

队列存储触发器Queue storage trigger

处理 blob 的另一种方法是编写对应于正在创建或修改的 blob 的队列消息,然后使用队列存储触发器开始处理。Another approach to processing blobs is to write queue messages that correspond to blobs being created or modified and then use a Queue storage trigger to begin processing.

示例Example

以下示例演示在 samples-workitems 容器中添加或更新 blob 时写入日志的 C# 函数The following example shows a C# function that writes a log when a blob is added or updated in the samples-workitems container.

[FunctionName("BlobTriggerCSharp")]        
public static void Run([BlobTrigger("samples-workitems/{name}")] Stream myBlob, string name, ILogger log)
{
    log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
}

blob 触发器路径 samples-workitems/{name} 中的字符串 {name} 会创建一个绑定表达式,可以在函数代码中使用它来访问触发 blob 的文件名。The string {name} in the blob trigger path samples-workitems/{name} creates a binding expression that you can use in function code to access the file name of the triggering blob. 有关详细信息,请参阅本文下文中的 Blob 名称模式For more information, see Blob name patterns later in this article.

有关 BlobTrigger 属性的详细信息,请参阅属性和注释For more information about the BlobTrigger attribute, see attributes and annotations.

特性和注释Attributes and annotations

对于 C# 类库,请使用以下属性来配置 blob 触发器:In C# class libraries, use the following attributes to configure a blob trigger:

  • BlobTriggerAttributeBlobTriggerAttribute

    该特性的构造函数采用一个表示要监视的容器的路径字符串,并选择性地采用某种 Blob 名称模式The attribute's constructor takes a path string that indicates the container to watch and optionally a blob name pattern. 下面是一个示例:Here's an example:

    [FunctionName("ResizeImage")]
    public static void Run(
        [BlobTrigger("sample-images/{name}")] Stream image,
        [Blob("sample-images-md/{name}", FileAccess.Write)] Stream imageSmall)
    {
        ....
    }
    

    可以设置 Connection 属性来指定要使用的存储帐户,如以下示例中所示:You can set the Connection property to specify the storage account to use, as shown in the following example:

    [FunctionName("ResizeImage")]
    public static void Run(
        [BlobTrigger("sample-images/{name}", Connection = "StorageConnectionAppSetting")] Stream image,
        [Blob("sample-images-md/{name}", FileAccess.Write)] Stream imageSmall)
    {
        ....
    }
    

    有关完整示例,请参阅触发器示例For a complete example, see Trigger example.

  • StorageAccountAttributeStorageAccountAttribute

    提供另一种方式来指定要使用的存储帐户。Provides another way to specify the storage account to use. 构造函数采用包含存储连接字符串的应用设置的名称。The constructor takes the name of an app setting that contains a storage connection string. 可以在参数、方法或类级别应用该特性。The attribute can be applied at the parameter, method, or class level. 以下示例演示类级别和方法级别:The following example shows class level and method level:

    [StorageAccount("ClassLevelStorageAppSetting")]
    public static class AzureFunctions
    {
        [FunctionName("BlobTrigger")]
        [StorageAccount("FunctionLevelStorageAppSetting")]
        public static void Run( //...
    {
        ....
    }
    

要使用的存储帐户按以下顺序确定:The storage account to use is determined in the following order:

  • BlobTrigger 特性的 Connection 属性。The BlobTrigger attribute's Connection property.
  • 作为 BlobTrigger 特性应用到同一参数的 StorageAccount 特性。The StorageAccount attribute applied to the same parameter as the BlobTrigger attribute.
  • 应用到函数的 StorageAccount 特性。The StorageAccount attribute applied to the function.
  • 应用到类的 StorageAccount 特性。The StorageAccount attribute applied to the class.
  • 函数应用的默认存储帐户(“AzureWebJobsStorage”应用设置)。The default storage account for the function app ("AzureWebJobsStorage" app setting).

配置Configuration

下表解释了在 function.json 文件和 BlobTrigger 特性中设置的绑定配置属性。The following table explains the binding configuration properties that you set in the function.json file and the BlobTrigger attribute.

function.json 属性function.json property Attribute 属性Attribute property 说明Description
typetype 不适用n/a 必须设置为 blobTriggerMust be set to blobTrigger. 在 Azure 门户中创建触发器时,会自动设置此属性。This property is set automatically when you create the trigger in the Azure portal.
directiondirection 不适用n/a 必须设置为 inMust be set to in. 在 Azure 门户中创建触发器时,会自动设置此属性。This property is set automatically when you create the trigger in the Azure portal. 用法部分中已阐述异常。Exceptions are noted in the usage section.
namename 不适用n/a 表示函数代码中的 Blob 的变量的名称。The name of the variable that represents the blob in function code.
路径path BlobPathBlobPath 要监视的容器The container to monitor. 可以是某种 Blob 名称模式May be a blob name pattern.
连接connection ConnectionConnection 包含要用于此绑定的存储连接字符串的应用设置的名称。The name of an app setting that contains the Storage connection string to use for this binding. 如果应用设置名称以“AzureWebJobs”开始,则只能在此处指定该名称的余下部分。If the app setting name begins with "AzureWebJobs", you can specify only the remainder of the name here. 例如,如果将 connection 设置为“MyStorage”,函数运行时将会查找名为“AzureWebJobsMyStorage”的应用设置。For example, if you set connection to "MyStorage", the Functions runtime looks for an app setting that is named "AzureWebJobsMyStorage." 如果将 connection 留空,函数运行时将使用名为 AzureWebJobsStorage 的应用设置中的默认存储连接字符串。If you leave connection empty, the Functions runtime uses the default Storage connection string in the app setting that is named AzureWebJobsStorage.

连接字符串必须属于某个常规用途存储帐户,而不能属于Blob 存储帐户The connection string must be for a general-purpose storage account, not a Blob storage account.

在本地进行开发时,应用设置将取 local.settings.json 文件的值。When you're developing locally, app settings go into the local.settings.json file.

使用情况Usage

可以将以下参数类型用于触发 blob:You can use the following parameter types for the triggering blob:

  • Stream
  • TextReader
  • string
  • Byte[]
  • ICloudBlob1ICloudBlob1
  • CloudBlockBlob1CloudBlockBlob1
  • CloudPageBlob1CloudPageBlob1
  • CloudAppendBlob1CloudAppendBlob1

1 function.json 中需有 "inout" 绑定 direction 或 C# 类库中需有 FileAccess.ReadWrite1 Requires "inout" binding direction in function.json or FileAccess.ReadWrite in a C# class library.

如果尝试绑定到某个存储 SDK 类型并收到错误消息,请确保已引用正确的存储 SDK 版本If you try to bind to one of the Storage SDK types and get an error message, make sure that you have a reference to the correct Storage SDK version.

由于整个 Blob 内容都会加载到内存中,因此,只有当 Blob 较小时才建议绑定到 stringByte[]Binding to string, or Byte[] is only recommended if the blob size is small, as the entire blob contents are loaded into memory. 平时,最好使用 StreamCloudBlockBlob 类型。Generally, it is preferable to use a Stream or CloudBlockBlob type. 有关详细信息,请参阅本文后面的并发和内存使用情况For more information, see Concurrency and memory usage later in this article.

Blob 名称模式Blob name patterns

可以在 function.jsonpath 属性中或者在 BlobTrigger 特性构造函数中指定 Blob 名称模式。You can specify a blob name pattern in the path property in function.json or in the BlobTrigger attribute constructor. 名称模式可以是筛选器或绑定表达式The name pattern can be a filter or binding expression. 以下部分提供了有关示例。The following sections provide examples.

获取文件名和扩展名Get file name and extension

以下示例演示如何分别绑定到 Blob 文件名和扩展名:The following example shows how to bind to the blob file name and extension separately:

"path": "input/{blobname}.{blobextension}",

如果 Blob 名为 original-Blob1.txt,则函数代码中 blobnameblobextension 变量的值为 original-Blob1txtIf the blob is named original-Blob1.txt, the values of the blobname and blobextension variables in function code are original-Blob1 and txt.

按 Blob 名称筛选Filter on blob name

以下示例仅根据 input 容器中以字符串“original-”开头的 Blob 触发:The following example triggers only on blobs in the input container that start with the string "original-":

"path": "input/original-{name}",

如果 Blob 名称为 original-Blob1.txt,则函数代码中 name 变量的值为 Blob1.txtIf the blob name is original-Blob1.txt, the value of the name variable in function code is Blob1.txt.

按文件类型筛选Filter on file type

以下示例仅根据 .png 文件触发:The following example triggers only on .png files:

"path": "samples/{name}.png",

按文件名中的大括号筛选Filter on curly braces in file names

若要查找文件名中的大括号,请使用两个大括号将大括号转义。To look for curly braces in file names, escape the braces by using two braces. 以下示例筛选名称中包含大括号的 Blob:The following example filters for blobs that have curly braces in the name:

"path": "images/{{20140101}}-{name}",

如果 Blob 名为 {20140101}-soundfile.mp3,则函数代码中的 name 变量值为 soundfile.mp3If the blob is named {20140101}-soundfile.mp3, the name variable value in the function code is soundfile.mp3.

MetadataMetadata

Blob 触发器提供了几个元数据属性。The blob trigger provides several metadata properties. 这些属性可在其他绑定中用作绑定表达式的一部分,或者用作代码中的参数。These properties can be used as part of binding expressions in other bindings or as parameters in your code. 这些值的语义与 CloudBlob 类型相同。These values have the same semantics as the CloudBlob type.

属性Property 类型Type 说明Description
BlobTrigger string 触发 Blob 的路径。The path to the triggering blob.
Uri System.Uri 主位置的 blob 的 URI。The blob's URI for the primary location.
Properties BlobPropertiesBlobProperties Blob 的系统属性。The blob's system properties.
Metadata IDictionary<string,string> Blob 的用户定义元数据。The user-defined metadata for the blob.

例如,以下 C# 脚本和 JavaScript 示例会记录触发 blob 的路径,包括容器:For example, the following C# script and JavaScript examples log the path to the triggering blob, including the container:

public static void Run(string myBlob, string blobTrigger, ILogger log)
{
    log.LogInformation($"Full blob path: {blobTrigger}");
} 

Blob 回执Blob receipts

Azure Functions 运行时确保没有为相同的新 blob 或更新 blob 多次调用 blob 触发器函数。The Azure Functions runtime ensures that no blob trigger function gets called more than once for the same new or updated blob. 为了确定是否已处理给定的 blob 版本,它会维护 blob 回执To determine if a given blob version has been processed, it maintains blob receipts.

Azure Functions 将 Blob 回执存储在函数应用的 Azure 存储帐户中名为 azure-webjobs-hosts 的容器中(由 AzureWebJobsStorage 应用设置定义)。Azure Functions stores blob receipts in a container named azure-webjobs-hosts in the Azure storage account for your function app (defined by the app setting AzureWebJobsStorage). Blob 回执包含以下信息:A blob receipt has the following information:

  • 触发的函数("<function app name>.Functions.<function name> ",例如:"MyFunctionApp.Functions.CopyBlob")The triggered function ("<function app name>.Functions.<function name>", for example: "MyFunctionApp.Functions.CopyBlob")
  • 容器名称The container name
  • Blob 类型("BlockBlob" 或 "PageBlob")The blob type ("BlockBlob" or "PageBlob")
  • Blob 名称The blob name
  • ETag(blob 版本标识符,例如:"0x8D1DC6E70A277EF")The ETag (a blob version identifier, for example: "0x8D1DC6E70A277EF")

若要强制重新处理某个 blob,可从 azure-webjobs-hosts 容器中手动删除该 blob 的 blob 回执。To force reprocessing of a blob, delete the blob receipt for that blob from the azure-webjobs-hosts container manually. 虽然重新处理可能不会立即发生,但它肯定会在稍后的时间点发生。While reprocessing might not occur immediately, it's guaranteed to occur at a later point in time. 若要立即重新处理,可以更新 azure-webjobs-hosts/blobscaninfo 中的 scaninfo Blob 。To reprocess immediately, the scaninfo blob in azure-webjobs-hosts/blobscaninfo can be updated. 将再次扫描 LatestScan 属性后具有上次修改时间戳的任何 Blob。Any blobs with a last modified timestamp after the LatestScan property will be scanned again.

有害 BlobPoison blobs

当给定 blob 的 blob 触发函数失败时,Azure Functions 将默认重试该函数共计 5 次。When a blob trigger function fails for a given blob, Azure Functions retries that function a total of 5 times by default.

如果 5 次尝试全部失败,Azure Functions 会将消息添加到名为 webjobs-blobtrigger-poison 的存储队列。If all 5 tries fail, Azure Functions adds a message to a Storage queue named webjobs-blobtrigger-poison. 最大尝试次数可配置。The maximum number of retries is configurable. 使用相同的 MaxDequeueCount 设置处理有害 Blob 和有害队列消息。The same MaxDequeueCount setting is used for poison blob handling and poison queue message handling. 有害 Blob 的队列消息是包含以下属性的 JSON 对象:The queue message for poison blobs is a JSON object that contains the following properties:

  • FunctionId(格式为 <function app name>.Functions.<function name> )FunctionId (in the format <function app name>.Functions.<function name>)
  • BlobType("BlockBlob" 或 "PageBlob")BlobType ("BlockBlob" or "PageBlob")
  • ContainerNameContainerName
  • BlobNameBlobName
  • ETag(blob 版本标识符,例如:"0x8D1DC6E70A277EF")ETag (a blob version identifier, for example: "0x8D1DC6E70A277EF")

并发和内存使用情况Concurrency and memory usage

Blob 触发器可在内部使用队列,因此并发函数调用的最大数量受 host.json 中的队列配置控制。The blob trigger uses a queue internally, so the maximum number of concurrent function invocations is controlled by the queues configuration in host.json. 默认设置会将并发限制到 24 个调用。The default settings limit concurrency to 24 invocations. 此限制分别应用于使用 blob 触发器的函数。This limit applies separately to each function that uses a blob trigger.

消耗计划将虚拟机 (VM) 上的函数应用限制为 1.5 GB 内存。The Consumption plan limits a function app on one virtual machine (VM) to 1.5 GB of memory. 内存由每个并发执行函数实例和函数运行时本身使用。Memory is used by each concurrently executing function instance and by the Functions runtime itself. 如果 blob 触发的函数将整个 blob 加载到内存中,该函数使用的仅用于 blob 的最大内存为 24 * 最大 blob 大小。If a blob-triggered function loads the entire blob into memory, the maximum memory used by that function just for blobs is 24 * maximum blob size. 例如,包含 3 个由 blob 触发的函数的函数应用和默认设置,其每 VM 最大并发为 3*24 = 72 个函数调用。For example, a function app with three blob-triggered functions and the default settings would have a maximum per-VM concurrency of 3*24 = 72 function invocations.

JavaScript 和 Java 函数会将整个 blob 加载到内存中,并且如果绑定到 stringByte[],则 C# 函数也会如此。JavaScript and Java functions load the entire blob into memory, and C# functions do that if you bind to string, or Byte[].

轮询Polling

轮询在检查日志和运行定期容器扫描之间起到混合作用。Polling works as a hybrid between inspecting logs and running periodic container scans. 每次以 10,000 个为一组扫描 Blob,并在间隔之间使用继续标记。Blobs are scanned in groups of 10,000 at a time with a continuation token used between intervals.

警告

此外,将“尽力”创建存储日志In addition, storage logs are created on a "best effort" basis. 不保证捕获所有事件。There's no guarantee that all events are captured. 在某些情况下可能会遗漏某些日志。Under some conditions, logs may be missed.

如果需要更快或更可靠的 blob 处理,在创建 blob 时,请考虑创建队列消息If you require faster or more reliable blob processing, consider creating a queue message when you create the blob. 然后,使用队列触发器而不是 Blob 触发器来处理 Blob。Then use a queue trigger instead of a blob trigger to process the blob. 另一个选项是使用事件网格;请参阅教程使用事件网格自动调整上传图像的大小Another option is to use Event Grid; see the tutorial Automate resizing uploaded images using Event Grid.

后续步骤Next steps