【问题标题】:CosmosDB lease collection is no longer being created automaticallyCosmosDB 租约集合不再自动创建
【发布时间】:2020-05-08 18:51:53
【问题描述】:

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:这是我能够从日志中提取的更详细的错误消息:

“源集合 'MyContainer'(在数据库 'MyDatabase' 中)或 租约集合“租约”(在数据库“MyDatabase”中)不 存在。在侦听器启动之前,这两个集合都必须存在。到 自动创建租约集合,设置 'CreateLeaseCollectionIfNotExists' 到 'true'

请注意,CreateLeaseCollectionIfNotExists 已设置为 true。

【问题讨论】:

  • 您能说明您正在使用的 Functions Cosmos DB 扩展包的版本吗?
  • 另外,对于要创建的租约集合,函数运行时需要能够正确初始化,请检查您的日志以查看运行时停止初始化时是否有错误。
  • 我正在使用 Microsoft.Azure.WebJobs.Extensions.CosmosDB 3.0.7 和 Microsoft.Azure.Cosmos 3.9.0-preview 和 Microsoft.NET.Sdk.Functions 3.0.3。
  • 在哪里可以找到函数运行时日志?
  • 它们会出现在 App Insights(如果您正在使用)docs.microsoft.com/en-us/azure/azure-functions/…。此外,如果您在 Azure 门户上浏览该功能,我相信屏幕底部有一个日志上拉选项。您是否尝试过在本地运行函数来调试任何初始化错误?

标签: azure azure-functions azure-cosmosdb azure-cosmosdb-changefeed


【解决方案1】:

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

这里的关键是要理解在函数初始化期间创建租赁集合,而不是在函数运行时。

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

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

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

你能做什么

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

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

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

【讨论】:

  • 哇。这是一个很好的答案。它帮助我澄清了很多事情。我会听从你的建议。您能否简单谈谈在函数应用程序运行时创建新集合和触发器时会发生什么?在生产中,我不会删除集合,但我可能会添加新集合。重新部署函数应用后,如何确保触发器适用于这些集合?
  • 关键是如何部署新的触发器。如果将触发器添加为已存在的函数应用项目的一部分,那么您将部署新位(使用新触发器)。这将导致函数应用程序重新启动。唯一的影响是其他触发器将在函数应用程序重新启动时停止消费,然后从它们工作的最后一个点恢复(您不会丢失更改,因为租用存储包含检查点)
  • @MatiasQuaranta 感谢您的精彩解释,但作为开发人员,我只想触发我的功能,我不介意管理租赁集合,这是您在路线图上计划的事情与 Function App 团队合作?一个简单的解决方案是清理 Function App init 上的租约集合并创建新文档
  • @MehdiBenmoha 不确定我是否关注。这个问题的场景是用户在函数运行时删除了租约集合。如果您不打算删除任何集合,则不会遇到此问题。如果租赁集合不存在,函数触发器会自动创建它,因此您无需管理它,您只需要不删除它即可。
  • @MatiasQuaranta 每次我使用 Ctrl+C 从我的 VSCode 终端停止该函数,或者如果与 CosmosDB 的连接以其他方式中断(不确定)时,它都会发生,并且它仅发生在一个函数使用来自另一个目录的共享代码。不知道是不是和问题有关,但是我有两个功能,一个不使用共享代码的还是会触发的。
猜你喜欢
  • 1970-01-01
  • 2016-01-26
  • 2020-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-09
  • 2019-08-17
  • 2016-05-02
相关资源
最近更新 更多