Azure Functions 并不总是在后续请求中获取具有输入 DocumentDB 绑定的文档

Azure Function does not always fetch document with input DocumentDB binding on subsequent requests

我的场景:收到一条来自 Azure 存储队列的消息,我想在 DocumentDB 中创建或更新文档

这是我的代码:

function.json

{
  "disabled": false,
  "bindings": [
    {
      "name": "updateEntry",
      "type": "queueTrigger",
      "direction": "in",
      "queueName": "update-log",
      "connection": "AzureWebJobsStorage"
    },
    {
      "type": "documentDB",
      "name": "inputDocument",
      "databaseName": "logging",
      "collectionName": "messages",
      "id": "{id}",
      "connection": "documentDB",
      "direction": "in"
    },
    {
      "type": "documentDB",
      "name": "outputDocument",
      "databaseName": "logging",
      "collectionName": "messages",
      "createIfNotExists": true,
      "connection": "documentDB",
      "direction": "out"
    }
  ]
}

run.csx

#r "Newtonsoft.Json"

using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

[Singleton(Mode = SingletonMode.Listener)]
public static void Run(UpdateEntryType updateEntry, TraceWriter log, DocumentType inputDocument, out DocumentType outputDocument)
{
    log.Info($"update entry:{updateEntry.id} {updateEntry.created} {updateEntry.Event.ToString()}");

    outputDocument = new DocumentType();
    outputDocument.Events = new List<JObject>();

    if (inputDocument == null)
    {
        outputDocument.id = updateEntry.id;
        outputDocument.created = updateEntry.created;
    }
    else
    {
        log.Info($"input document:{inputDocument.id} {inputDocument.created} {inputDocument.Events.Count}");
        outputDocument.id = inputDocument.id;
        outputDocument.created = updateEntry.created.CompareTo(inputDocument.created) < 0 ? updateEntry.created : inputDocument.created;
        outputDocument.Events.AddRange(inputDocument.Events);
    }

    outputDocument.Events.Add(updateEntry.Event);

    log.Info($"output document:{outputDocument.id} {outputDocument.created} {outputDocument.Events.Count}");
}

public class UpdateEntryType
{
    public string id { get; set; }
    public string created { get; set; }
    public JObject Event { get; set; }
}

public class DocumentType
{
    public string id { get; set; }
    public string created { get; set; }
    public List<JObject> Events { get; set; }
}

我的问题:大多数情况下,实际存在的文档是用 id 找到的,因此会更新 - 但至少有 5% 的时间不会

我的问题(在我打开案例之前@MSFT 支持): 我错过了什么?这是正确的方法还是注定要失败?

not for at least 5% of the time

根据我的经验,如果它是 专用 计划,我们需要为我们的 Function App 打开 Always On 设置。

The Function runtime will go idle after a few minutes of inactivity, so only HTTP triggers will actually "wake up" your functions. This is similar to how WebJobs must have Always On enabled.

关于Consumption Plan & Dedicated App Service Plan以及如何设置appsetting的详细信息,请参考Enable Always On when running on dedicated App Service Plan .

使用 Queue batchSize 1 而不是 SingletonMode.Listener 使问题消失。

hosts.json

{
  "queues": {
    "batchSize": 1
}