Отклик Cosmos DB 408 в функции Azure - PullRequest
3 голосов
/ 08 ноября 2019

У меня есть функция Azure (v2), которая обращается к базе данных Cosmos, но не через привязку (нам нужно использовать пользовательские параметры сериализации). Я следовал примеру здесь для настройки объекта, который затем должен быть доступен для всех экземпляров функции Activity. Мой немного отличается, потому что наш пользовательский объект 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 и тем, чтоЯ также поиграл с настройками host.json для durableTask вроде maxConcurrentActivityFunctions и maxConcurrentOrchestratorFunctions, но пока безрезультатно.

Как мне подойти к этой ошибке 408? Какие шаги я могу рассмотреть, чтобы уменьшить ее, кроме увеличения времени ожидания запроса?

Обновление 1. Я увеличил время запроса по умолчанию. до 5 минут, и теперь я получаю 503 ответа.

Обновление 2: указание на клон, опубликованный для функции Azure в плане Premium, похоже, работает после нескольких тестов.

Обновление 3: Мы не тестировали это достаточно сложно. Проблема выставлена ​​и на Премиум-плане. GitHub Выпуск готовится.

Обновление 4: Похоже, мы решили эту проблему с помощью комбинации режима Gateway при подключении к Космосу и увеличения количества RU.

1 Ответ

0 голосов
/ 08 ноября 2019

Тайм-аут действительно может сигнализировать о проблемах с ресурсами экземпляра. Справка: https://docs.microsoft.com/azure/cosmos-db/troubleshoot-dot-net-sdk#request-timeouts

Если вы работаете с функциями, посмотрите на соединения. Также проверьте использование процессора в экземплярах. Если ЦП высок, это может повлиять на задержку запросов и в конечном итоге получить тайм-ауты.

Для функций вы, безусловно, можете использовать 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;
            });
        }
    }
}

И тогда вы можете сделать ваши функции не статичными и добавить их:

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