创建多个适用于 Cosmos DB 的 Azure Functions 触发器Create multiple Azure Functions triggers for Cosmos DB

本文介绍如何配置多个适用于 Cosmos DB 的 Azure Functions 触发器,以并行工作并独立地对更改做出反应。This article describes how you can configure multiple Azure Functions triggers for Cosmos DB to work in parallel and independently react to changes.

基于事件的无服务器 Functions 使用适用于 Cosmos DB 的 Azure Functions 触发器并共享租用容器

基于事件的体系结构要求Event-based architecture requirements

使用 Azure Functions 生成无服务器体系结构时,建议创建协同工作的小型函数集,而不是长时间运行的大型函数。When building serverless architectures with Azure Functions, it's recommended to create small function sets that work together instead of large long running functions.

在使用适用于 Cosmos DB 的 Azure Functions 触发器生成基于事件的无服务器流时,只要特定 Azure Cosmos 容器中存在新事件,就会遇到要执行多项操作的方案。As you build event-based serverless flows using the Azure Functions trigger for Cosmos DB, you'll run into the scenario where you want to do multiple things whenever there is a new event in a particular Azure Cosmos container. 如果要触发的操作彼此独立,理想的解决方案是为每个要执行的操作创建一个适用于 Cosmos DB 的 Azure Functions 触发器,所有触发器侦听同一 Azure Cosmos 容器上的更改 。If actions you want to trigger, are independent from one another, the ideal solution would be to create one Azure Functions triggers for Cosmos DB per action you want to do, all listening for changes on the same Azure Cosmos container.

优化多个触发器的容器Optimizing containers for multiple Triggers

鉴于适用于 Cosmos DB 的 Azure Functions 触发器的要求,我们需要第二个容器来存储状态,也称为租用容器 。Given the requirements of the Azure Functions trigger for Cosmos DB, we need a second container to store state, also called, the leases container. 这是否意味着每个 Azure 函数需要一个单独的租用容器?Does this mean that you need a separate leases container for each Azure Function?

可以使用以下两个选项:Here, you have two options:

  • 为每个函数创建一个租用容器 :除非使用共享吞吐量数据库,否则此方法可能会转化为其他成本。Create one leases container per Function: This approach can translate into additional costs, unless you're using a shared throughput database. 请记住,容器级别的最小吞吐量是 400 个请求单位,对于租用容器,它仅用于检查进度和维护状态。Remember, that the minimum throughput at the container level is 400 Request Units, and in the case of the leases container, it is only being used to checkpoint the progress and maintain state.
  • 创建一个租用容器并为所有函数共享 :第二个选项更好地利用了容器上预配的请求单元,因为它允许多个 Azure Functions 共享和使用相同的预配吞吐量。Have one lease container and share it for all your Functions: This second option makes better use of the provisioned Request Units on the container, as it enables multiple Azure Functions to share and use the same provisioned throughput.

本文的目的是指导你完成第二个选项。The goal of this article is to guide you to accomplish the second option.

配置共享的租用容器Configuring a shared leases container

若要配置共享的租用容器,需要在触发器上进行的唯一额外配置是在使用 C# 时添加 LeaseCollectionPrefix 属性,或在使用 JavaScript 时添加 leaseCollectionPrefix 属性To configure the shared leases container, the only extra configuration you need to make on your triggers is to add the LeaseCollectionPrefix attribute if you are using C# or leaseCollectionPrefix attribute if you are using JavaScript. 属性的值应是特定触发器的逻辑描述符。The value of the attribute should be a logical descriptor of what that particular trigger.

例如,如果有三个触发器:一个发送电子邮件,一个执行聚合以创建具体化视图,一个将更改发送到另一个存储,供以后分析,那么可以将“电子邮件”的 LeaseCollectionPrefix 分配到第一个触发器,“具体化”分配到第二个触发器,“分析”分配到第三个触发器。For example, if you have three Triggers: one that sends emails, one that does an aggregation to create a materialized view, and one that sends the changes to another storage, for later analysis, you could assign the LeaseCollectionPrefix of "emails" to the first one, "materialized" to the second one, and "analytics" to the third one.

重要的是,所有三个触发器都可以使用相同的租用容器配置(帐户、数据库和容器名称) 。The important part is that all three Triggers can use the same leases container configuration (account, database, and container name).

请参阅以下非常简单的代码示例,该示例使用 C# 中的 LeaseCollectionPrefix 属性:A very simple code samples using the LeaseCollectionPrefix attribute in C#, would look like this:

using Microsoft.Azure.Documents;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;

[FunctionName("SendEmails")]
public static void SendEmails([CosmosDBTrigger(
    databaseName: "ToDoItems",
    collectionName: "Items",
    ConnectionStringSetting = "CosmosDBConnection",
    LeaseCollectionName = "leases",
    LeaseCollectionPrefix = "emails")]IReadOnlyList<Document> documents,
    ILogger log)
{
    ...
}

[FunctionName("MaterializedViews")]
public static void MaterializedViews([CosmosDBTrigger(
    databaseName: "ToDoItems",
    collectionName: "Items",
    ConnectionStringSetting = "CosmosDBConnection",
    LeaseCollectionName = "leases",
    LeaseCollectionPrefix = "materialized")]IReadOnlyList<Document> documents,
    ILogger log)
{
    ...
}

对于 JavaScript,可以使用 leaseCollectionPrefix 属性在 function.json 文件上应用配置:And for JavaScript, you can apply the configuration on the function.json file, with the leaseCollectionPrefix attribute:

{
    "type": "cosmosDBTrigger",
    "name": "documents",
    "direction": "in",
    "leaseCollectionName": "leases",
    "connectionStringSetting": "CosmosDBConnection",
    "databaseName": "ToDoItems",
    "collectionName": "Items",
    "leaseCollectionPrefix": "emails"
},
{
    "type": "cosmosDBTrigger",
    "name": "documents",
    "direction": "in",
    "leaseCollectionName": "leases",
    "connectionStringSetting": "CosmosDBConnection",
    "databaseName": "ToDoItems",
    "collectionName": "Items",
    "leaseCollectionPrefix": "materialized"
}

Note

始终监视共享租用容器上预配的请求单元。Always monitor on the Request Units provisioned on your shared leases container. 共享租用容器的每个触发器都将增加吞吐量平均消耗,因此可能需要在增加使用它的 Azure Functions 的数量时增加预配的吞吐量。Each Trigger that shares it, will increase the throughput average consumption, so you might need to increase the provisioned throughput as you increase the number of Azure Functions that are using it.

后续步骤Next steps