【问题标题】:Azure Function CosmosDb Trigger processes same documents over and overAzure Function CosmosDb 触发器一遍又一遍地处理相同的文档
【发布时间】:2019-06-12 22:43:05
【问题描述】:

我有一个由 CosmosDb 插入/更新触发的函数,我将每个文档复制到一个存储 blob。调试时,该函数会一遍又一遍地触发相同的少数文档。

我尝试限制处理的文档数量,但这使得它只能一遍又一遍地处理相同的 N 个文档。我尝试在触发器集合(和租约集合)上提高 RU,但没有效果。

[FunctionName("Function1")]
        public async static Task Run([CosmosDBTrigger(
            databaseName: "Events",
            collectionName: "DomainEvents",
            ConnectionStringSetting = "cosmosConnectionString",
            CreateLeaseCollectionIfNotExists = true,
            LeaseCollectionName = "DomainEventLeases")]IReadOnlyList<Document> input, ILogger log, ExecutionContext context)
        {
            if (input != null && input.Count > 0)
            {
                var config = new ConfigurationBuilder()
                 .SetBasePath(context.FunctionAppDirectory)
                 .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                 .AddEnvironmentVariables()
                 .Build();

                CloudStorageAccount cloudStorageAccount;

                if (CloudStorageAccount.TryParse(config["StorageConnectionAppSetting"], out cloudStorageAccount))
                {
                    var client = cloudStorageAccount.CreateCloudBlobClient();
                    var container = client.GetContainerReference("wormauditlog");

                    foreach(var thisDocument in input)
                    {
                        var blob = container.GetBlockBlobReference(thisDocument.Id);

                        try
                        {
                            await blob.UploadFromByteArrayAsync(thisDocument.ToByteArray(), 0, thisDocument.ToByteArray().Length);
                        }
                        catch(Exception e)
                        {
                            throw;
                        }
                    }
                }
                else
                {
                    throw new FunctionInvocationException("Bad storage connection string.");
                }

            }
        }

【问题讨论】:

  • 你需要返回Task而不是void
  • @StephenCleary 我关注的文档示例使用 void 方法 (docs.microsoft.com/en-us/azure/azure-functions/…) 显示了它。我已将其更改为一项任务,它的行为与以前完全相同。
  • void 很好。 async void 不是。
  • 啊,我明白了。谢谢。不过还是不行……

标签: azure azure-functions azure-cosmosdb azure-triggers


【解决方案1】:

触发器不会重试文档批次,您可能正在接收相同文档的更新。

如果您检查操作的时间戳thisDocument.GetPropertyValue&lt;int&gt;("_ts"),您会看到这些是不同的值。

Change Feed 包含插入和更新操作,如果您的架构多次更新同一个文档,那么预计 Change Feed 中会有多个条目对应同一个文档 ID。

另外,不相关的会很好,你在每次执行时创建一个CloudStorageAccount 的实例,一个好的模式是维护一个实例并共享它,通过依赖注入或延迟初始化(参见@ 987654321@).

【讨论】:

  • Re:Cosmos 触发器 - 我一遍又一遍地被相同的文档触发,是的,但它没有保存不同的数据。它不断尝试用 cosmos 中的相同数据更新这 8 个文档,并且不会发生变化。我正在使用专用的测试集合,并且那里没有发生插入或更新。此外,这是一个事件溯源日志。文档只写在那里一次,永远不会更新或删除。我还通过设置断点检查了文档上的时间戳,允许函数运行,检查数据,让它再次运行,再次检查。相同的 _ts 数据。
  • 回复:云存储帐户 - 感谢您的意见。这是秒杀代码。我们在所有生产级功能中都使用 Core DI。
  • 触发代码不会重试,也不会重新发送相同的批次。如果你去检查租约集合,你应该在那里找到带有ContinuationToken 属性的文件,状态是什么?它们会在函数执行后更改值吗?
  • 我检查了租约集合,当函数运行时,这些文件永远不会改变。他们总是有这个:“PartitionId”:“0”,“Owner”:“33f1d3f3-114c-474c-8831-7cf345d3f62e”,“ContinuationToken”:“\”11\””,“properties”:{},跨度>
  • 作为一个实验,我从一个完整的空白集合开始。该函数启动并创建租约集合。然后它等待来自 cosmos 的更新消息。然后我放入了一个简化的文档。该功能再次开始一次又一次地在同一更新上触发。该集合的继续标记是“\”2\“”。所以,它确实似乎一次又一次地发射它。
猜你喜欢
  • 1970-01-01
  • 2019-08-29
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多