Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье приводятся рекомендации по повышению производительности и надежности бессерверных приложений-функций. Более общий набор рекомендаций по функциям Azure см. в рекомендациях по функциям Azure.
Ниже приведены рекомендации по созданию и проектированию бессерверных решений с помощью Функций Azure.
Избегайте длительных по времени выполнения функций
Большие длительные функции могут вызвать непредвиденные проблемы со временем ожидания. Дополнительные сведения о продолжительности времени ожидания для заданного плана размещения см. в разделе продолжительность времени ожидания приложения функций.
Функция может стать большой из-за многих Node.js зависимостей. Импорт зависимостей также может привести к увеличению времени загрузки, что приводит к непредвиденным тайм-аутам. Зависимости загружаются как явно, так и неявно. Один модуль, загруженный вашим кодом, может загружать дополнительные собственные модули.
По возможности рефакторить большие функции, разбивая их на более мелкие, которые взаимодействуют и возвращают результат быстро. Например, функция веб-перехватчика или HTTP-триггера может потребовать ответа подтверждения в определённый срок, так как обычно веб-перехватчики требуют немедленного ответа. Вы можете передать полезные данные триггера HTTP в очередь, чтобы их обработала функция триггера очереди. Такой подход позволяет отложить фактическую работу и вернуть немедленный ответ.
Убедитесь, что фоновые задачи завершены
Когда функция запускает все задачи, обратные вызовы, потоки, процессы, они должны завершиться до возврата кода функции. Поскольку Функции не отслеживают эти фоновые потоки, завершение работы сайта может происходить независимо от их состояния, что может привести к непреднамеренному поведению в ваших функциях.
Например, если функция запускает фоновую задачу и возвращает успешный ответ до завершения задачи, среда выполнения Функций считает выполнение успешно завершенным независимо от результата фоновой задачи. Если эта фоновая задача выполняет важную работу, она может быть прервана остановкой работы сайта, оставляя эту работу в неизвестном состоянии.
Взаимодействие между функциями
Устойчивые функции и Azure Logic Apps создаются для управления переходами состояния и обменом данными между несколькими функциями.
Если для интеграции с несколькими функциями не используются устойчивые функции или приложения логики, рекомендуется использовать очереди хранилища для обмена данными между функциями. Основной причиной является то, что очереди хранилища дешевле и гораздо проще подготавливать, чем другие варианты хранения.
Отдельные сообщения в очереди хранилища ограничены размером до 64 КБ. Если необходимо передать большие сообщения между функциями, можно использовать очередь служебной шины Azure для поддержки размеров сообщений до 256 КБ на уровне "Стандартный" и до 100 МБ на уровне "Премиум".
Топики в служебной шине полезны, если требуется фильтрация сообщений перед обработкой.
Центры событий полезны для поддержки больших объемов обмена данными.
Напишите функции, которые не сохраняют состояние
По возможности, функции должны быть бездейственными и идемпотентными. Свяжите всю необходимую информацию о состоянии с вашими данными. Например, обрабатываемый заказ, скорее всего, будет иметь связанный state
элемент. Функция может обрабатывать заказ на основе этого состояния, пока сама функция остается без состояния.
Идемпотентные функции особенно рекомендуются для использования с триггерами таймера. Например, если у вас есть что-то, что абсолютно должно выполняться один раз в день, напишите его, чтобы он может работать в любое время в течение дня с одинаковыми результатами. Функция может завершить выполнение, если в определенный день не будет работы. Кроме того, если предыдущий запуск завершился сбоем, следующий запуск должен продолжить с того места, на котором остановился. Это особенно важно для привязок на основе сообщений, которые выполняют повторную попытку при сбое. Дополнительные сведения см. в разделе "Проектирование функций Azure" для идентичных входных данных.
Создание оборонительных функций
Предположим, что функция может столкнуться с исключением в любое время. Создайте функции с возможностью продолжить работу с предыдущей точки сбоя во время следующего выполнения. Рассмотрим сценарий, требующий следующих действий:
- Запрос на 10 000 строк в базе данных.
- Создайте сообщение очереди для каждой из этих строк для дальнейшей обработки на следующем этапе.
В зависимости от сложности вашей системы, у вас могут возникнуть такие проблемы, как неправильное поведение подключённых сервисов, сетевые сбои или достижение квот и т. д. Всё это может в любой момент повлиять на вашу функцию. Разработайте ваши функции таким образом, чтобы они были готовы к этому.
Как код реагирует на сбой после вставки 5000 этих элементов в очередь для обработки? Отслеживайте элементы в наборе заданий, которые вы завершили. В противном случае их можно вставить еще раз. Это двойная вставка может оказать серьезное влияние на рабочий процесс, поэтому сделайте функции идемпотентными.
Если элемент очереди уже обработан, разрешите вашей функции стать no-op.
Воспользуйтесь преимуществами оборонительных мер, уже предоставляемых для компонентов, используемых на платформе Функций Azure. Например, ознакомьтесь с инструкциями по обработке сообщений о подозрительных очередях в документации по триггерам и привязкам очереди службы хранилища Azure.
Для функций на основе HTTP рекомендуется использовать стратегии управления версиями API с помощью службы "Управление API Azure". Например, если необходимо обновить приложение-функцию HTTP, разверните новое обновление в отдельном приложении-функции и используйте редакции или версии службы управления API для перенаправления клиентов на новую версию или редакцию. После того как все клиенты используют версию или ревизию, и выполнение в предыдущем функциональном приложении завершено, вы можете отключить предыдущее функциональное приложение.
Рекомендации по организации функций
В рамках решения вы можете разрабатывать и публиковать несколько функций. Эти функции часто объединяются в одно приложение-функцию, но они также могут выполняться в отдельных приложениях-функциях. В планах размещения "Премиум" и "Служба приложений" несколько функциональных приложений также могут совместно использовать одни и те же ресурсы, работая в рамках одного и того же плана. Способ группировки функций и приложений-функций может повлиять на производительность, масштабирование, конфигурацию, развертывание и безопасность общего решения. Существуют не правила, которые применяются к каждому сценарию, поэтому при планировании и разработке функций учитывайте сведения в этом разделе.
Упорядочение функций для повышения производительности и масштабирования
Каждая созданная функция имеет объем памяти. Хотя объем этого ресурса обычно невелик, слишком большое количество функций в функции-приложении может привести к замедлению запуска на новых экземплярах. Это также означает, что общее использование памяти приложения-функции может быть выше. Трудно сказать, сколько функций должно находиться в одном приложении, которое зависит от конкретной рабочей нагрузки. Однако если функция хранит много данных в памяти, рассмотрите возможность меньше функций в одном приложении.
Если вы запускаете несколько приложений-функций в одном плане premium или выделенном плане (служба приложений), эти приложения совместно используют одни и те же ресурсы, выделенные плану. Если у вас есть одно приложение-функция с гораздо более высоким требованием к памяти, чем другие, оно использует непропорциональное количество ресурсов памяти на каждом экземпляре, в котором развертывается приложение. Т.к. это может оставлять меньше памяти для других приложений на каждом экземпляре, вам может потребоваться запустить приложение-функцию, потребляющее много памяти, в отдельном плане размещения.
Замечание
При использовании плана потребления рекомендуется всегда помещать каждое приложение в свой собственный план, так как приложения масштабируются независимо в любом случае. Дополнительные сведения см. в разделе "Несколько приложений" в одном плане.
Рассмотрим, следует ли группировать функции с различными профилями нагрузки. Например, если у вас есть функция, обрабатывающая много тысяч сообщений очереди, а другая , которая вызывается только иногда, но имеет высокие требования к памяти, может потребоваться развернуть их в отдельных приложениях-функциях, чтобы они получили собственные наборы ресурсов и масштабируются независимо друг от друга.
Упорядочение функций для конфигурации и развертывания
Функциональные приложения имеют host.json
файл, который используется для настройки расширенного поведения триггеров функций и среды выполнения Azure Functions. Изменения в host.json
файле применяются ко всем функциям в приложении. Если у вас есть функции, требующие пользовательских конфигураций, рассмотрите возможность их перемещения в собственное приложение функций.
Все функции в вашем локальном проекте развертываются вместе как набор файлов в ваше приложение-функцию в Azure. Может потребоваться развернуть отдельные функции отдельно или использовать такие функции, как слоты развертывания для некоторых функций, а не другие. В таких случаях следует развернуть эти функции (в отдельных проектах кода) в разных приложениях-функциях.
Упорядочивание функций по привилегиям
Строки подключения и другие учетные данные, хранящиеся в параметрах приложения, предоставляют всем функциям в функциональном приложении одинаковый набор разрешений для связанного ресурса. Рекомендуется свести к минимуму количество функций с доступом к определенным учетным данным, переместив те из них, которые не используют такие учетные данные, в отдельное приложение-функцию. Для передачи данных между функциями в различных приложениях-функциях всегда можно использовать такие методы, как связывание функций.
Рекомендации по масштабируемости
Существует ряд факторов, влияющих на масштабирование экземпляров функционального приложения. Сведения приведены в документации по масштабированию функций. Ниже приведены некоторые рекомендации по обеспечению оптимальной масштабируемости приложения-функции.
Управление подключениями и общий доступ к ним
Повторное использование подключений к внешним ресурсам по возможности. Узнайте , как управлять подключениями в Функциях Azure.
Избегание совместного использования учетных записей хранения
При создании приложения-функции необходимо связать его с учетной записью хранения. Подключение учетной записи хранилища сохраняется в параметре приложения AzureWebJobsStorage.
Чтобы увеличить производительность, используйте для каждого приложения-функции отдельную учетную запись хранения. Этот подход особенно важен при наличии устойчивых функций или триггерных функций Центров событий, которые создают большой объем транзакций хранения. Если логика приложения взаимодействует со службой хранилища Azure напрямую (с помощью пакета SDK службы хранилища) или с помощью одной из привязок к хранилищу, следует использовать выделенную учетную запись хранения. Например, если у вас есть функция, запускаемая концентратором событий, записывающая некоторые данные в хранилище блоб-объектов, используйте две учетные записи хранения: одну для функции приложения и другую для блоб-объектов, которые хранит функция.
Не используйте тестовый и рабочий код в одном приложении-функции
Функции в функциональном приложении совместно используют ресурсы. Например, к памяти предоставлен общий доступ. Если вы используете приложение-функцию в рабочей среде, не добавляйте в нее тестовые функции и ресурсы. Это может привести к непредвиденным издержкам во время выполнения рабочего кода.
Будьте осторожны, что вы загружаете в приложениях рабочих функций. Среднее значение памяти вычисляется для каждой функции в приложении.
Если у вас есть общая сборка, на которой ссылается несколько функций .NET, поместите ее в общую папку. В противном случае можно случайно развернуть несколько версий одного двоичного файла, которые ведут себя по-разному между функциями.
Не используйте подробное ведение журнала в рабочем коде, что негативно влияет на производительность.
Использование асинхронного кода без блокирующих вызовов
Асинхронное программирование рекомендуется, особенно при блокировке операций ввода-вывода.
В C# всегда избегайте ссылки на свойство Result
или вызова метода Wait
для экземпляра Task
. Такой подход может привести к исчерпанию потоков.
Подсказка
Если вы планируете использовать привязки HTTP или веб-перехватчика, спланируйте работу так, чтобы избежать нехватки портов, которая может возникнуть в результате неправильной установки HttpClient
. См. дополнительные сведения об управлении подключениями в службе "Функции Azure".
Использование нескольких рабочих процессов
По умолчанию любой экземпляр узла для функций использует один рабочий процесс. Чтобы повысить производительность, особенно в однопоточных средах выполнения, таких как Python, используйте FUNCTIONS_WORKER_PROCESS_COUNT для увеличения числа рабочих процессов на узел (до 10). Затем Функции Azure пытаются равномерно распределять одновременные вызовы функций между этими рабочими процессами.
FUNCTIONS_WORKER_PROCESS_COUNT применяется к каждому узлу, создаваемому функциями при масштабировании приложения для удовлетворения потребности.
По возможности получайте сообщения в пакетном режиме
Некоторые триггеры, такие как Концентратор событий, позволяют получать пакет сообщений по одному вызову. Пакетные сообщения имеют гораздо более высокую производительность. Максимальный размер пакета в файле можно настроить, как описано в host.json
справочной документации поhost.json
Для функций C# можно изменить тип на строго типизированный массив. Например, вместо сигнатуры EventData sensorEvent
метода может быть EventData[] sensorEvent
. Для других языков необходимо явно задать свойство кардинальности в function.json
many
, чтобы включить пакетную обработку , как показано здесь.
Настройте поведение узла для обеспечения оптимального параллелизма
Файл host.json
в приложении-функции позволяет настроить среду выполнения узла и поведение триггеров. Помимо поведения пакетной обработки, вы можете управлять параллелизмом для ряда триггеров. Часто настройка этих параметров помогает масштабировать каждый экземпляр согласно требованиям вызванных функций.
Параметры в файле host.json применяются ко всем функциям приложения в одном экземпляре функции. Например, если у вас есть функциональное приложение с двумя HTTP-функциями и с 25 установленными maxConcurrentRequests
запросами, то запрос к любому HTTP-триггеру будет подсчитываться в пользу общих 25 одновременных запросов. Если это приложение-функция масштабируется до 10 экземпляров, десять функций эффективно позволяют 250 одновременных запросов (10 экземпляров * 25 одновременных запросов на экземпляр).
Другие параметры конфигурации узла приведены в статье о конфигурацииhost.json.
Дальнейшие шаги
Дополнительные сведения см. в следующих ресурсах: