Azure 函数中的 Cosmos DB 408 响应

Sco*_*y H 6 azure azure-functions azure-cosmosdb

我有一个访问 Cosmos DB 的 Azure 函数(v2),但不是通过绑定(我们需要使用自定义序列化设置)。我已经按照此处的示例设置了一个对象,然后该对象应该可用于活动函数的所有实例。我的有点不同,因为我们的自定义CosmosDb对象需要一个awaitfor 设置。

public static class AnalyzeActivityTrigger
{
    private static readonly Lazy<Task<CosmosDb>> LazyCosmosDb = new Lazy<Task<CosmosDb>>(InitializeDocumentClient);
    private static Task<CosmosDb> CosmosDb => LazyCosmosDb.Value;

    private static Task<CosmosDb> InitializeDocumentClient()
    {
        return StorageFramework.CosmosDb.GetCosmosDb(DesignUtilities.Storage.CosmosDbContainerDefinitions, DesignUtilities.Storage.CosmosDbMigrations);
    }

    [FunctionName(nameof(AnalyzeActivityTrigger))]
    public static async Task<Guid> Run(
        [ActivityTrigger]DurableActivityContext context,
        ILogger log)
    {
        var analyzeActivityRequestString = context.GetInput<string>();
        var analyzeActivityRequest = StorageFramework.Storage.Deserialize<AnalyzeActivityRequest>(analyzeActivityRequestString);
        var componentDesign = StorageFramework.Storage.Deserialize<ComponentDesign>(analyzeActivityRequest.ComponentDesignString);

        var (analysisSet, _, _) = await AnalysisUtilities.AnalyzeComponentDesignAndUploadArtifacts(componentDesign,
            LogVariables.Off, new AnalysisLog(), Stopwatch.StartNew(), analyzeActivityRequest.CommitName, await CosmosDb);

        return analysisSet.AnalysisReport.Guid;
    }
}
Run Code Online (Sandbox Code Playgroud)

我们扇出,并行调用这个活动函数。我们的文档相当大,因此更新它们的成本很高,而这正是此代码的一部分。

我有时会在container.ReplaceItemAsync调用时收到此错误:

响应状态代码不表示成功:408 子状态:0 原因:(消息:请求超时。...

显而易见的事情似乎是增加超时,但这是否表明存在其他问题?增加超时似乎是解决症状而不是问题。我们也有代码可以在这一切发生之前扩展我们的 RU。我想知道这是否与 Azure Functions 散开以及给它带来太多负载有关。因此,我还尝试durableTask了调整likemaxConcurrentActivityFunctions和的host.json 设置maxConcurrentOrchestratorFunctions,但到目前为止都无济于事。

我应该如何处理这个 408 错误?除了增加请求超时之外,我可以考虑采取哪些措施来缓解它?

更新 1:我将默认请求超时增加到 5 分钟,现在我收到了 503 个响应。

更新 2:指向在高级计划中发布到 Azure 函数的克隆似乎在多次测试后有效。

更新 3:我们没有足够努力地测试它。这个问题也出现在 Premium 计划中。GitHub 问题即将发布。

更新 4:我们似乎通过结合使用网关模式连接到 Cosmos 和增加 RU 来解决这个问题。

Mat*_*nta 1

超时确实可以表明有关实例资源的问题。参考:https://learn.microsoft.com/azure/cosmos-db/troubleshoot-dot-net-sdk#request-timeouts

如果您在函数上运行,请查看连接。还要验证实例中的 CPU 使用情况。如果 CPU 较高,可能会影响请求延迟并最终导致超时。

对于函数,您当然可以使用 DI 来避免整个 Lazy 声明:https://github.com/Azure/azure-cosmos-dotnet-v3/tree/master/Microsoft.Azure.Cosmos.Samples/Usage/AzureFunctions

创建一个Startup.cs文件:

using System;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(YourNameSpace.Startup))]

namespace YourNameSpace
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddSingleton((s) => {
                CosmosClient cosmosClient = new CosmosClient("connection string");

                return cosmosClient;
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使你的函数不是静态的并注入它:

public class AnalyzeActivityTrigger
{
    private readonly CosmosClient cosmosClient;
    public AnalyzeActivityTrigger(CosmosClient cosmosClient)
    {
        this.cosmosClient = cosmosClient;
    }

    [FunctionName(nameof(AnalyzeActivityTrigger))]
    public async Task<Guid> Run(
        [ActivityTrigger]DurableActivityContext context,
        ILogger log)
    {
        var analyzeActivityRequestString = context.GetInput<string>();
        var analyzeActivityRequest = StorageFramework.Storage.Deserialize<AnalyzeActivityRequest>(analyzeActivityRequestString);
        var componentDesign = StorageFramework.Storage.Deserialize<ComponentDesign>(analyzeActivityRequest.ComponentDesignString);

        var (analysisSet, _, _) = await AnalysisUtilities.AnalyzeComponentDesignAndUploadArtifacts(componentDesign,
            LogVariables.Off, new AnalysisLog(), Stopwatch.StartNew(), analyzeActivityRequest.CommitName, this.cosmosClient);

        return analysisSet.AnalysisReport.Guid;
    }
}
Run Code Online (Sandbox Code Playgroud)