【问题标题】:Automatic retry to CosmosDb output binding自动重试到 CosmosDb 输出绑定
【发布时间】:2018-06-05 08:48:34
【问题描述】:

我正在使用一个 Azure 函数,该函数通过输出绑定将包含大约 200 个文档的数组发送到 CosmosDB。队列消息同时触发了大约 1000 个函数。

在某些情况下,我收到“请求率很大”错误并且函数执行失败。 documentation 说当这个错误发生时,我可以在几毫秒内重试执行,但我怀疑 azure 函数运行时正在为我做这件事。我找不到任何文档明确说明当输出绑定抛出该异常时,它将自动重试(就像使用 .NET Linq 库一样)。

有人能指出我是否是这种情况吗?

【问题讨论】:

    标签: azure azure-functions azure-cosmosdb


    【解决方案1】:

    Output 绑定使用已经具备重试机制的 SDK 1.13.2。

    假设您使用的是 Azure Functions v1,如果您使用的是 IAsyncCollection,该函数将为每个 AddAsync 执行一个 UpsertDocumentAsync,如果您使用的是单个文档输出,那么应该会发生 UpsertDocumentAsync一次。

    无论如何,SDK 默认重试9 times 对一个节流结果,之后,异常冒泡,你的函数会出错;根据QueueTrigger 设计,文档应该返回队列进行重试,经过几次迭代后,它会进入死信队列。

    如果您想要更精细地控制流程,您可以获取DocumentClient 并使用try/catch 自己执行UpsertDocumentAsync,如果失败超过9 次,您可以选择发送到另一个队列或重试另一组时间。比如:

    using Microsoft.Azure.Documents;
    using Microsoft.Azure.Documents.Client;
    using Microsoft.Azure.Documents.Linq;
    
    [FunctionName("CosmosDBSample")]
    public static async Task<HttpResponseMessage> Run(
        [QueueTrigger("my-queue")] MyPOCOClass myMessage, 
        [DocumentDB("test", "test", ConnectionStringSetting = "CosmosDB"] DocumentClient client, 
        TraceWriter log)
    {
        try
        {
            await client.UpsertDocumentAsync(myMessage);
        }
        catch(DocumentClientException ex)
        {
            // retry / queue somewhere else?
            log.Warning($"DocumentClientException {ex.Message} in document {myMessage.Id}.");
        }
    }
    

    【讨论】:

    • 感谢您的意见。只是为了后代,我能够通过不使用服务总线队列输出绑定将消息发送到队列来解决,这反过来又会触发对 CosmosDB 执行 200 个 upsert 的函数。我使用 Service Bus SDK 发送消息,将 Retry Count 参数增加到 10。这样就处理了所有文档。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    相关资源
    最近更新 更多