Знаете ли вы, что может быть причиной того, что мое функциональное приложение Azure выдает ошибку 503 после запуска через 30 секунд?

#azure #function

Вопрос:

` [functionName(«FileShareDirRead02»)] публичный статический асинхронный запуск задачи ( [HttpTrigger(AuthorizationLevel.Функция, «get», «post», Route = null)] Запрос HttpRequest, журнал ILogger)

     {   
        //Get the contents of the POST and store them into local variables  
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);

        //The following variable values are being passed in to the function through HTTP POST, or via parameters specified in the data factory pipeline
        string storageAccount = data.storageAccount; //Name of storage account containing the fileshare you plan to parse and remove files
        string fileshare = data.fileShare;  //Name of the fileshare within the storage account
        string folderPath = data.folderPath;  // with no leading slash, this will be considered the ROOT of the fileshare. Parsing only goes down from here, never up.
        string keyVaultName = data.keyvaultName; //Name of the key valut where the storage SAS token is stored
        int daysoldbeforeDeletion = data.daysoldbeforeDeletion;  //Number of days old a file must be before it is deleted from the fileshare
        string nameofSASToken = data.nameofsasToken;  //Name of SAS token created through PowerShell prior to execution of this function

        string storageAccountSAS = storageAccount   "-"   nameofSASToken; //Format of the storage account SAS name
        string kvUri = "https://"   keyVaultName   ".vault.azure.net/";  //URI to the key vault
       
        var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());  //Instantiate an instance of a SecretClient using the key vault URI
        var storageKey1 = await client.GetSecretAsync(storageAccountSAS);  //Obtain SAS Token from key vault

        string key = storageKey1.Value.Value;   //Assign key the SIG value which is part of the SAS Token
        key = key.Substring(1);  //Trim the leading question mark from the key value since it is not a part of the key

        string connectionString = "FileEndpoint=https://"   storageAccount   ".file.core.windows.net/;SharedAccessSignature="   key;   //Define the connection string to be used when creating a Share Client
        ShareClient share = new ShareClient(connectionString,fileshare);  // Instantiate a ShareClient which will be used to manipulate the file share
        
        var folders = new List<Tuple<string, string>>();  //reference a new list 2-tuple named folders which will include our directories from our share in our Azure Storage Account
        ShareDirectoryClient directory = share.GetDirectoryClient(folderPath);   // Get a reference to the directory supplied in the POST
        
        Queue<ShareDirectoryClient> remaining = new Queue<ShareDirectoryClient>();  // Track the remaining directories to walk, starting from the folder path provided in the POST
        remaining.Enqueue(directory);
            while (remaining.Count > 0) // Keep scanning until all folders and files have been evaluated
            {
                ShareDirectoryClient dir = remaining.Dequeue(); // Get all of the next directory's files and subdirectories
                if (dir.GetFilesAndDirectoriesAsync() != null) //Make sure the folder path exists in the fileshare
                {
                    //return new OkObjectResult("{"childItems":"   JsonConvert.SerializeObject(remaining.Count)   "}");  //Returns a list of all files which were removed from the fileshare
                    await foreach (ShareFileItem item in dir.GetFilesAndDirectoriesAsync())  //For each directory and file
                    {
                            if (!(item.IsDirectory))  //Make sure the item is not a directory before executing the below code
                            {
                                ShareFileClient fileClient = new ShareFileClient(connectionString, fileshare, dir.Path   "/"   item.Name);  //Create the File Service Client
                                if (fileClient.Exists())
                                {
                                    ShareFileProperties properties = await fileClient.GetPropertiesAsync();   //Get the properties of the current file
                                    DateTime convertedtime = properties.LastModified.DateTime;  //Get the last modified date and time of the current file
                                    DateTime date = DateTime.UtcNow;  //Get today's date and time
                                    TimeSpan timeSpan = date.Subtract(convertedtime);  //Subtract last modified date/time from today's date/time
                                    int dayssincelastmodified = timeSpan.Days;   //Assign the number of days between the two dates
                                    if (dayssincelastmodified > daysoldbeforeDeletion)
                                    {
                                        folders.Add(new Tuple<string, string>(item.Name, fileClient.Path));  // Add the directory names and filenames to our list 2-tuple
                                        fileClient.Delete();  //Delete the file from the share
                                    }
                                }
                            }
                            if (item.IsDirectory)  // Keep walking down directories
                            {
                                remaining.Enqueue(dir.GetSubdirectoryClient(item.Name));
                            }
                    }
                }
            }
            return new OkObjectResult("{"childItems":"   JsonConvert.SerializeObject(folders)   "}");  //Returns a list of all files which were removed from the fileshare
    }
}
 

}`Я написал функциональное приложение с использованием MS Visual Studio C # и опубликовал его в функциональном приложении Azure. Приложение очень простое. Он считывает каталог и все подкаталоги общего файлового ресурса в поисках файлов, которые не были изменены за последние 90 дней. Если это так, файлы удаляются. Эта функция отлично работает при чтении небольшого набора каталогов и файлов. Но когда я запускаю его в каталоге, скажем, с 1000 или более файлами, приложение вылетает с ошибкой 503, в которой говорится, что служба недоступна, и для проверки позже. Я использую стандартный план обслуживания приложений. Я подумал, что, возможно, истекло время ожидания, но этот тип плана не должен препятствовать запуску приложения, независимо от того, как долго оно выполняется. Чтобы быть уверенным, я поместил строку в свой файл host.json «functionTimeout»: «01:00:00», чтобы убедиться, что это не проблема. Я не могу найти ни одной записи в журнале, которая объясняет, что происходит. Есть идеи о том, как отладить эту проблему?

Комментарии:

1. Пожалуйста, предоставьте достаточно кода, чтобы другие могли лучше понять или воспроизвести проблему.

2. Время выполнения функций Azure ограничено тем, как долго может выполняться функция кода. Это время выполнения было ограничено жестким ограничением, изначально установленным на 5 минут для плана потребления. Ваша функция занимает более 5 минут?

Ответ №1:

Эта проблема часто вызывается проблемами уровня приложения, такими как:

  • запросы занимают много времени
  • приложение, использующее большую память / процессор
  • сбой приложения из-за исключения.

Похоже, что вашей функции требуется больше времени для возврата HTTP-ответа. Как указано в документации, 230 секунд — это максимальное время, которое может потребоваться функции, запускаемой HTTP, для ответа на запрос. Пожалуйста, обратитесь к этому.

Кроме того, установка соответствующего значения для параметра «functionTimeout» host.json файла «также может избежать автозапуска функции Azure. Вы упомянули, что вы также установили время ожидания функции равным 1 часу.

Для устранения этой проблемы обратитесь к документации azure-app-service-troubleshootes-http-502-http-503 MSFT и следуйте инструкциям по устранению неполадок.

Для увеличения времени обработки используйте асинхронный шаблон Azure Durable Functions. Обратитесь к этой ссылке.

Комментарии:

1. Я не нажимаю тайм-аут ответа HTTP, поскольку он составляет 230 секунд, и мое приложение, если сбой происходит только через 30 секунд. Я использую план обслуживания приложений, в котором не должно быть тайм-аута. На самом деле я не думаю, что это проблема, поскольку приложение работает всего около 30 секунд. Я подозреваю, что это как-то связано с производительностью, но я также настроил автоматическое масштабирование с 3 дополнительными узлами, и это не имело никакого значения вообще. Затем я увеличил тип машины до самого большого доступного и автоматически увеличил его до 10. Та же проблема.

2. @Tim, вы выполнили шаги по устранению неполадок, в нем содержится несколько решений проблем!

3. Да, я ознакомился с советами по устранению неполадок, но они не помогли. Очень сложно даже найти какое-либо упоминание о проблеме в файлах журнала. Приложение не генерирует исключение, для ответа не требуется 230 секунд, оно настроено на бесконечный запуск в файле host.json. Я также попытался добавить дополнительные рабочие узлы, но это не улучшило производительность. Он по-прежнему останавливался почти в то же время, что и раньше.