Оптимизация производительности и надежности Функций AzureOptimize the performance and reliability of Azure Functions

В этой статье описано, как повысить производительность и надежность бессерверных приложений-функций.This article provides guidance to improve the performance and reliability of your serverless function apps.

Общие рекомендацииGeneral best practices

Ниже приведены рекомендации по созданию и разработке бессерверных решений с помощью службы "Функции Azure".The following are best practices in how you build and architect your serverless solutions using Azure Functions.

Избегайте длительных функцийAvoid long running functions

Крупные длительные функции могут вызывать непредвиденные проблемы времени ожидания.Large, long-running functions can cause unexpected timeout issues. Дополнительные сведения о времени ожидания для заданного плана размещения см. в разделе время ожидания приложения-функции.To learn more about the timeouts for a given hosting plan, see function app timeout duration.

Функция может стать большой, так как многие Node.js зависимости.A function can become large because of many Node.js dependencies. Импорт зависимостей может также привести к замедлению загрузки, что, в свою очередь, приводит к непредвиденным проблемам времени ожидания.Importing dependencies can also cause increased load times that result in unexpected timeouts. Зависимости можно загрузить явно и неявно.Dependencies are loaded both explicitly and implicitly. Один модуль, загруженный в коде, может загрузить собственные дополнительные модули.A single module loaded by your code may load its own additional modules.

По возможности выполняйте рефакторинг крупных функций и перерабатывайте их на более мелкие совместимые наборы функций, которые работают сообща и быстро возвращают ответ.Whenever possible, refactor large functions into smaller function sets that work together and return responses fast. Например, для веб-перехватчика или функции триггера HTTP может потребоваться ответ подтверждения в течение определенного предела времени. для веб-перехватчиков обычно требуется немедленный отклик.For example, a webhook or HTTP trigger function might require an acknowledgment response within a certain time limit; it's common for webhooks to require an immediate response. Полезные данные триггера HTTP можно передать в очередь для обработки с помощью функции триггера очереди.You can pass the HTTP trigger payload into a queue to be processed by a queue trigger function. Такой подход позволяет отложить фактическую работу и вернуть немедленный ответ.This approach lets you defer the actual work and return an immediate response.

Взаимодействие функцийCross function communication

Устойчивые функции и Azure Logic Apps используются для управления переходами состояний и обмена данными между несколькими функциями.Durable Functions and Azure Logic Apps are built to manage state transitions and communication between multiple functions.

Если не используется Устойчивые функции или Logic Apps для интеграции с несколькими функциями, лучше использовать очереди хранилища для обмена данными между функциями.If not using Durable Functions or Logic Apps to integrate with multiple functions, it's best to use storage queues for cross-function communication. Основная причина заключается в том, что очереди хранилища являются более дешевыми и проще в подготовке, чем другие варианты хранения.The main reason is that storage queues are cheaper and much easier to provision than other storage options.

Размер отдельных сообщений в очереди хранилища ограничен до 64 КБ.Individual messages in a storage queue are limited in size to 64 KB. Если между функциями нужно передать сообщения большего размера, можно использовать очередь служебной шины Azure, которая поддерживает сообщения размером до 256 КБ на уровне "Стандартный" и 1 МБ на уровне "Премиум".If you need to pass larger messages between functions, an Azure Service Bus queue could be used to support message sizes up to 256 KB in the Standard tier, and up to 1 MB in the Premium tier.

Если перед обработкой сообщений их нужно отфильтровать, ознакомьтесь со статьями о служебной шине.Service Bus topics are useful if you require message filtering before processing.

Для поддержки обмена крупными сообщениями используются Центры событий.Event hubs are useful to support high volume communications.

Создавайте функции без отслеживания состоянияWrite functions to be stateless

По возможности функции должны быть без отслеживания состояния и идемпотентными.Functions should be stateless and idempotent if possible. Свяжите любые необходимые сведения о состоянии со своими данными.Associate any required state information with your data. Например, с обрабатываемым заказом скорее всего будет связан элемент state.For example, an order being processed would likely have an associated state member. Функция может обработать заказ, основываясь на этом состоянии, но в ней самой при этом не отслеживается состояние.A function could process an order based on that state while the function itself remains stateless.

Идемпотентные функции рекомендуется использовать с триггерами таймера.Idempotent functions are especially recommended with timer triggers. Например, если у вас есть нечто, что должно выполняться раз в день, напишите его, чтобы оно можно было выполнять в любое время в течение дня с теми же результатами.For example, if you have something that absolutely must run once a day, write it so it can run anytime during the day with the same results. Функция может выйти из программы, если она не работает в определенный день.The function can exit when there's no work for a particular day. Кроме того, если предыдущее выполнение завершилось ошибкой, следующее выполнение должно начаться с прерванного момента.Also if a previous run failed to complete, the next run should pick up where it left off.

Создавайте защищенные функцииWrite defensive functions

Предположим, что в любое время в функции может возникнуть исключение.Assume your function could encounter an exception at any time. Реализуйте в функции возможность продолжения с предыдущей точки сбоя во время следующего выполнения.Design your functions with the ability to continue from a previous fail point during the next execution. Давайте рассмотрим сценарий, в котором необходимо сделать следующее:Consider a scenario that requires the following actions:

  1. Запрос 10 000 строк в базе данных.Query for 10,000 rows in a database.
  2. Создать сообщение очереди для каждой из этих строк для дальнейшей обработки.Create a queue message for each of those rows to process further down the line.

В зависимости от того, насколько сложна система, у вас может быть: вовлечение подчиненных служб в неплохое поведение, сбои сети или достигнутые квоты и т. д. Все это может повлиять на вашу функцию в любое время.Depending on how complex your system is, you may have: involved downstream services behaving badly, networking outages, or quota limits reached, etc. All of these can affect your function at any time. Функции необходимо подготавливать к таким проблемам.You need to design your functions to be prepared for it.

Как отреагирует ваш код при сбое после вставки 5000 элементов в очередь для обработки?How does your code react if a failure occurs after inserting 5,000 of those items into a queue for processing? Отслеживайте элементы в наборе, работа с которым завершена.Track items in a set that you’ve completed. В противном случае их можно вставить позже.Otherwise, you might insert them again next time. Такая двойная Вставка может оказать серьезное воздействие на рабочий процесс, поэтому функция идемпотентными.This double-insertion can have a serious impact on your work flow, so make your functions idempotent.

Если элемент очереди уже обработан, разрешите холостой цикл выполнения функции.If a queue item was already processed, allow your function to be a no-op.

Воспользуйтесь предоставленными возможностями защиты для компонентов, используемых на платформе Функций Azure.Take advantage of defensive measures already provided for components you use in the Azure Functions platform. Например, ознакомьтесь с разделом Обработка подозрительных сообщений очереди в документации по триггерам и привязкам очереди службы хранилища Azure.For example, see Handling poison queue messages in the documentation for Azure Storage Queue triggers and bindings.

Рекомендации по масштабируемостиScalability best practices

Существует ряд факторов, влияющих на то, как экземпляры приложения-функции масштабируются.There are a number of factors that impact how instances of your function app scale. Дополнительные сведения см. в документации по масштабированию функций.The details are provided in the documentation for function scaling. Ниже приведены рекомендации по оптимальному масштабированию приложения-функции.The following are some best practices to ensure optimal scalability of a function app.

Управление подключениями и общий доступ к нимShare and manage connections

При возможности повторно используйте подключения к внешним ресурсам.Reuse connections to external resources whenever possible. См. раздел Способы управления подключениями в службе "Функции Azure".See how to manage connections in Azure Functions.

Избегайте совместного использования учетных записей храненияAvoid sharing storage accounts

При создании приложения-функции необходимо связать его с учетной записью хранения.When you create a function app, you must associate it with a storage account. Подключение к учетной записи хранения сохраняется в параметре приложения AzureWebJobsStorage.The storage account connection is maintained in the AzureWebJobsStorage application setting.

Чтобы повысить производительность, используйте отдельную учетную запись хранения для каждого приложения-функции.To maximize performance, use a separate storage account for each function app. Это особенно важно, если у вас есть Устойчивые функции или функции, активируемые концентратором событий, которые создают большой объем транзакций хранилища.This is particularly important when you have Durable Functions or Event Hub triggered functions, which both generate a high volume of storage transactions. Если логика приложения взаимодействует с хранилищем Azure напрямую (с помощью пакета SDK хранилища) или с помощью одной из привязок к хранилищу, следует использовать выделенную учетную запись хранения.When your application logic interacts with Azure Storage, either directly (using the Storage SDK) or through one of the storage bindings, you should use a dedicated storage account. Например, если у вас есть функция, активируемая концентратором событий, записывая некоторые данные в хранилище BLOB-объектов, используйте две учетные записи хранения — один для приложения-функции, а другую для больших двоичных объектов, хранимых функцией.For example, if you have an Event Hub-triggered function writing some data to blob storage, use two storage accounts—one for the function app and another for the blobs being stored by the function.

Не используйте тестовый и рабочий код в одном приложении-функцииDon't mix test and production code in the same function app

Функции в приложении-функции совместно используют ресурсы.Functions within a function app share resources. Например, память.For example, memory is shared. Если приложение-функция используется в рабочей среде, не добавляйте в нее тестовые функции и ресурсы.If you're using a function app in production, don't add test-related functions and resources to it. Это может вызвать непредвиденные затраты во время выполнения кода в рабочей среде.It can cause unexpected overhead during production code execution.

Следите за тем, что вы загружаете в рабочие приложения-функции.Be careful what you load in your production function apps. Память усредняется для каждой функции в приложении.Memory is averaged across each function in the app.

Если у вас есть общая сборка, на которую имеется ссылка в нескольких функциях .NET, поставьте ее в общую общую папку.If you have a shared assembly referenced in multiple .NET functions, put it in a common shared folder. В противном случае можно случайно развернуть несколько версий одного и того же двоичного файла, которые ведут себя по-разному в разных функциях.Otherwise, you could accidentally deploy multiple versions of the same binary that behave differently between functions.

Не используйте подробный журнал в рабочем коде, что отрицательно сказывается на производительности.Don't use verbose logging in production code, which has a negative performance impact.

Использование асинхронного кода без блокирующих вызововUse async code but avoid blocking calls

Рекомендуется использовать асинхронное программирование, особенно если вовлечены блокирующие операции ввода-вывода.Asynchronous programming is a recommended best practice, especially when blocking I/O operations are involved.

В C# всегда Избегайте обращения к Result свойству или вызывающему Wait методу в Task экземпляре.In C#, always avoid referencing the Result property or calling Wait method on a Task instance. Применение этого подхода может привести к нехватке потоков.This approach can lead to thread exhaustion.

Совет

Если вы планируете использовать привязки HTTP или веб-перехватчика, спланируйте работу так, чтобы избежать нехватки портов, которая может возникнуть в результате неправильной установки HttpClient.If you plan to use the HTTP or WebHook bindings, plan to avoid port exhaustion that can be caused by improper instantiation of HttpClient. См. дополнительные сведения об управлении подключениями в службе "Функции Azure".For more information, see How to manage connections in Azure Functions.

Использование нескольких рабочих процессовUse multiple worker processes

По умолчанию любой экземпляр узла для функций использует один рабочий процесс.By default, any host instance for Functions uses a single worker process. Чтобы повысить производительность, особенно при использовании однопотоковых сред выполнения, таких как Python, используйте FUNCTIONS_WORKER_PROCESS_COUNT , чтобы увеличить количество рабочих процессов на узел (до 10).To improve performance, especially with single-threaded runtimes like Python, use the FUNCTIONS_WORKER_PROCESS_COUNT to increase the number of worker processes per host (up to 10). Затем Функции Azure пытаются равномерно распределять одновременные вызовы функций между этими рабочими процессами.Azure Functions then tries to evenly distribute simultaneous function invocations across these workers.

FUNCTIONS_WORKER_PROCESS_COUNT применяется к каждому узлу, создаваемому функциями при масштабировании приложения для удовлетворения потребности.The FUNCTIONS_WORKER_PROCESS_COUNT applies to each host that Functions creates when scaling out your application to meet demand.

По возможности получайте сообщения в пакетном режимеReceive messages in batch whenever possible

Некоторые триггеры, например триггер концентратора событий, позволяют получать сообщения в пакетном режиме в рамках одного вызова.Some triggers like Event Hub enable receiving a batch of messages on a single invocation. Пакетная обработка сообщений обеспечивает более высокую производительность.Batching messages has much better performance. Вы можете настроить максимальный размер пакета в файле host.json, как описано в справочной документации по host.json.You can configure the max batch size in the host.json file as detailed in the host.json reference documentation

Для функций C# можно изменить тип на строго типизированный массив.For C# functions, you can change the type to a strongly-typed array. Например, вместо EventData sensorEvent можно использовать сигнатуру метода EventData[] sensorEvent.For example, instead of EventData sensorEvent the method signature could be EventData[] sensorEvent. Для других языков необходимо явно задать свойство кратности в function.json , чтобы many включить пакетную обработку , как показано ниже.For other languages, you'll need to explicitly set the cardinality property in your function.json to many in order to enable batching as shown here.

Настройте поведение узла для обеспечения оптимального параллелизмаConfigure host behaviors to better handle concurrency

Файл host.json в приложении-функции позволяет настраивать среду выполнения узла и поведение триггера.The host.json file in the function app allows for configuration of host runtime and trigger behaviors. Кроме настройки поведения пакетной обработки, вы можете управлять параллелизмом определенного числа триггеров.In addition to batching behaviors, you can manage concurrency for a number of triggers. Часто настройка этих параметров помогает масштабировать каждый экземпляр согласно требованиям вызванных функций.Often adjusting the values in these options can help each instance scale appropriately for the demands of the invoked functions.

Параметры в host.jsфайле применяются ко всем функциям в приложении в рамках одного экземпляра функции.Settings in the host.json file apply across all functions within the app, within a single instance of the function. Например, если у вас есть приложение-функция с двумя функциями HTTP и maxConcurrentRequests запросами, для которых задано значение 25, запрос к любому триггеру HTTP будет считаться общим 25 одновременных запросов.For example, if you had a function app with two HTTP functions and maxConcurrentRequests requests set to 25, a request to either HTTP trigger would count towards the shared 25 concurrent requests. Если это приложение-функция масштабируется до 10 экземпляров, то две функции эффективно допускают 250 параллельных запросов (10 экземпляров * 25 одновременных запросов на экземпляр).When that function app is scaled to 10 instances, the two functions effectively allow 250 concurrent requests (10 instances * 25 concurrent requests per instance).

Другие параметры конфигурации узла находятся в разделеhost.json Configuration.Other host configuration options are found in the host.json configuration article.

Следующие шагиNext steps

Дополнительные сведения см. в следующих ресурсах:For more information, see the following resources: