不再自动创建 CosmosDB 租约集合

CosmosDB lease collection is no longer being created automatically

我在使用 CosmosDBAzure Functions 时遇到了一个非常奇怪的问题。我经常删除我的数据库并在 DEV 中重新创建它。然后我重新部署函数应用程序。当我在应用程序中调用 API 并调用 CosmosDB 触发器时,我通常会看到创建了 leases 集合。这是一个典型的触发器:

[FunctionName("MyTrigger")]
public static async Task RunAsync([CosmosDBTrigger("MyDatabase", "MyContainer",
ConnectionStringSetting = "CosmosConnectionString", LeaseCollectionName = "leases", 
LeaseCollectionPrefix = "MyTrigger", CreateLeaseCollectionIfNotExists = true)]IReadOnlyList<Document> documents, 
ExecutionContext executionContext)
{
     // code
}

由于某种原因,leases 集合不再创建。我重新创建了数据库,多次重新部署函数应用程序并进行了 API 调用,但没有成功。我错过了什么?

编辑: 我查看了日志并注意到 The lease was lost 消息有很多 Microsoft.Azure.Documents.ChangeFeedProcessor.Exceptions.LeaseLostException 异常,所以我不确定是什么继续。

EDIT2: 这是我能够从日志中提取的更详细的错误消息:

"Either the source collection 'MyContainer' (in database 'MyDatabase') or the lease collection 'leases' (in database 'MyDatabase') does not exist. Both collections must exist before the listener starts. To automatically create the lease collection, set 'CreateLeaseCollectionIfNotExists' to 'true'

请注意 CreateLeaseCollectionIfNotExists 已设置为 true。

Either the source collection... 错误来自此处:https://github.com/Azure/azure-webjobs-sdk-extensions/blob/0683d1bd08a16680c70f982ad00c940b7e9c1fce/src/WebJobs.Extensions.CosmosDB/Trigger/CosmosDBTriggerListener.cs#L140 它对在尝试启动触发器进程时检测到的 NotFound 做出反应。

这里的关键是了解租赁集合的创建是在函数初始化期间发生的,而不是在函数处于 运行ning 时。

如果您在函数处于 运行ning 时删除租赁集合(或受监控集合),您可能会看到由 运行ning 实例生成的错误弹出窗口。如果出现新实例(由于缩放)或您重新启动函数,则创建将在 https://github.com/Azure/azure-webjobs-sdk-extensions/blob/0683d1bd08a16680c70f982ad00c940b7e9c1fce/src/WebJobs.Extensions.CosmosDB/Trigger/CosmosDBTriggerAttributeBindingProvider.cs#L155 中开始。

那么,这些错误是什么时候发生的?

  1. 函数初始化 -> CreateIfNotExist 检查并创建 Leases 集合。如果失败,则初始化在此停止。这会产生一条错误消息。
  2. Function 运行ning -> Instances can be 运行ning 如果租约被删除 运行time 错误将使 Function 代码重试以再次启动进程,因为重试不会再次 运行 初始化,它输出 Either the source collection...
  3. 偶尔 The lease was lost 发生在负载平衡场景中,当租约(来自租约集合)分配给新实例时,多个 Function 实例正在 运行 宁和分配缩放负载。如果触发器尝试更新检查点并且您突然删除了租约集合,也会发生这种情况。

你能做什么

如果您手动删除租约集合,那么您可以控制可能发生的情况。建议是:

  1. 停止你的函数
  2. 删除租约集合
  3. 启动您的函数。

如果您不停止函数,并且如果您在 运行宁时删除租约存储,函数的行为是完全未定义的。