Azure Function中的Cosmos DB 408响应

时间:2019-11-08 00:54:38

标签: azure azure-functions azure-cosmosdb

我有一个访问Cosmos DB的Azure函数(v2),但没有通过绑定访问(我们需要使用自定义序列化设置)。我遵循了示例here的示例,该示例设置了一个对象,然后该对象应可用于活动功能的所有实例。我的有点不同,因为我们的自定义CosmosDb对象需要await进行设置。

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;
    }
}

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

有时在调用container.ReplaceItemAsync时会出现此错误:

  

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

显而易见的事情似乎是增加了超时时间,但这是否可以指示其他问题呢?增加超时似乎是在解决症状而不是解决问题。我们还具有在所有这些发生之前扩展RU的代码。我想知道这是否与Azure Functions散开有关,并给它带来了太多的负担。因此,我也尝试过像maxConcurrentActivityFunctionsmaxConcurrentOrchestratorFunctions那样调整host.json settings for durableTask,但到目前为止没有用。

我应该如何处理此408错误?除了增加请求超时时间外,我还可以考虑采取哪些措施来缓解这种情况?

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

更新2:在多次测试之后,指向指向Premium计划上的Azure功能发布的克隆似乎可以正常工作。

更新3:我们的测试不够严谨。该问题也显示在高级计划中。 GitHub即将发布。

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

1 个答案:

答案 0 :(得分:0)

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

如果您正在运行功能,请查看连接。还要验证实例中的CPU使用率。如果CPU过高,则可能会影响请求延迟并最终导致超时。

对于函数,您当然可以使用DI来避免整个惰性声明: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;
            });
        }
    }
}

然后您可以使Functions不是静态的并注入它:

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;
    }
}