Функции очереди задач используют Google Cloud Tasks, чтобы помочь вашему приложению выполнять ресурсоемкие задачи, требующие много времени или ограниченные по пропускной способности, асинхронно, вне основного потока приложения.
Например, вы хотите создать резервные копии большого набора графических файлов, которые в настоящее время размещены в API с ограничением частоты запросов. Чтобы быть ответственным потребителем этого API, вам необходимо соблюдать ограничения на частоту запросов. Кроме того, такие длительные задания могут завершаться сбоем из-за превышения времени ожидания и ограничений памяти.
Чтобы упростить этот процесс, вы можете написать функцию очереди задач, которая задает основные параметры задачи, такие как scheduleTime и dispatchDeadline, а затем передает функцию в очередь в Cloud Tasks. Среда Cloud Tasks разработана специально для того, чтобы обеспечивать эффективный контроль перегрузки и политики повторных попыток для таких операций.
Firebase SDK для Cloud Functions for Firebase версии 3.20.1 и выше взаимодействует с Firebase Admin SDK версии 10.2.0 и выше, чтобы поддерживать функции очереди задач.
Использование функций очереди задач с Firebase может привести к дополнительным расходам на обработку данных в Cloud Tasks. Дополнительную информацию можно найти в статье Цены на Cloud Tasks.
Как создать функции очереди задач
Чтобы использовать функции очереди задач, выполните следующие действия:
- Напишите функцию очереди задач, используя SDK Firebase для Cloud Functions.
- Протестируйте функцию, запустив ее с помощью HTTP-запроса.
- Разверните функцию с помощью Firebase CLI. При первом развертывании функции очереди задач CLI создаст очередь задач в Cloud Tasks с параметрами (ограничение частоты запросов и повторная попытка), указанными в исходном коде.
- Добавьте задачи в созданную очередь, при необходимости передав параметры для настройки расписания выполнения. Для этого вы можете написать код с помощью Admin SDK и развернуть его в Cloud Functions for Firebase.
Как написать функции очереди задач
Чтобы начать писать функции очереди задач, используйте onDispatch. Важная часть написания функции очереди задач – настройка повторных попыток и ограничения частоты запросов для каждой очереди. Примеры кода на этой странице основаны на приложении, которое настраивает сервис, создающий резервные копии всех изображений из Астрономической картинки дня НАСА.
Как настроить функции очереди задач
Функции очереди задач поставляются с мощным набором параметров конфигурации, позволяющих точно контролировать ограничение частоты запросов и поведение повторных попыток очереди задач:
exports.backupApod = functions
.runWith( {secrets: ["NASA_API_KEY"]})
.tasks.taskQueue({
retryConfig: {
maxAttempts: 5,
minBackoffSeconds: 60,
},
rateLimits: {
maxConcurrentDispatches: 6,
},
}).onDispatch(async (data) => {
retryConfig.maxAttempts=5: каждая задача в очереди задач автоматически повторяется до пяти раз. Это помогает устранить временные ошибки, например ошибки сети или временные сбои в работе зависимого внешнего сервиса.retryConfig.minBackoffSeconds=60– каждая задача повторяется не ранее чем через 60 секунд после предыдущей попытки. Это обеспечивает большой буфер между каждой попыткой, поэтому мы не спешим исчерпать 5 попыток повтора слишком быстро.rateLimits.maxConcurrentDispatch=6: одновременно отправляется не более шести задач. Это помогает обеспечить стабильный поток запросов к базовой функции и сократить количество активных экземпляров и холодных запусков.
Тестирование функций очереди задач
В большинстве случаев эмулятор Cloud Functions – лучший способ протестировать функции очереди задач. В документации Emulator Suite рассказывается, как настроить приложение для эмуляции функций очереди задач.
Кроме того, функции очереди задач представлены как простые функции HTTP в Firebase Local Emulator Suite. Вы можете протестировать эмулированную функцию задачи, отправив запрос HTTP POST с полезной нагрузкой данных JSON:
# start the Firebase Emulators
firebase emulators:start
# trigger the emulated task queue function
curl \
-X POST # An HTTP POST request...
-H "content-type: application/json" \ # ... with a JSON body
http://localhost:$PORT/$PROJECT_ID/$REGION/$NAME \ # ... to function url
-d '{"data": { ... some data .... }}' # ... with JSON encoded data
Развертывание функций очереди задач
Разверните функцию очереди задач с помощью интерфейса командной строки Firebase:
$ firebase deploy --only functions:backupApod
При первом развертывании функции очереди задач CLI создает очередь задач в Cloud Tasks с параметрами (ограничение частоты запросов и повторная попытка), указанными в исходном коде.
Если при развертывании функций возникают ошибки, связанные с разрешениями, убедитесь, что пользователю, выполняющему команды развертывания, назначены соответствующие роли IAM.
Как добавить функции очереди задач в очередь
Функции очереди задач можно добавлять в очередь в Cloud Tasks из доверенной серверной среды, например Cloud Functions for Firebase, с помощью Firebase Admin SDK для Node.js. Если вы раньше не работали с Admin SDK, прочитайте статью Как добавить Firebase на сервер.
Обычно Admin SDK создает новую задачу, добавляет ее в очередь в Cloud Tasks и задает для нее конфигурацию:
exports.enqueueBackupTasks = functions.https.onRequest(
async (_request, response) => {
const queue = getFunctions().taskQueue("backupApod");
const enqueues = [];
for (let i = 0; i <= 10; i += 1) {
// Enqueue each task with i*60 seconds delay. Our task queue function
// should process ~1 task/min.
const scheduleDelaySeconds = i * 60
enqueues.push(
queue.enqueue(
{ id: `task-${i}` },
{
scheduleDelaySeconds,
dispatchDeadlineSeconds: 60 * 5 // 5 minutes
},
),
);
}
await Promise.all(enqueues);
response.sendStatus(200);
});
scheduleDelaySeconds– образец кода пытается распределить выполнение задач, связывая задержку в N минут с N-й задачей. Это означает, что запускается примерно одна задача в минуту. Обратите внимание, что вы также можете использоватьscheduleTime, если хотите, чтобы Cloud Tasks запускал задачу в определенное время.dispatchDeadlineSeconds: максимальное время, в течение которого Cloud Tasks будет ждать завершения задачи. Cloud Tasks будет повторять задачу в соответствии с конфигурацией повторных попыток очереди или до достижения этого срока. В примере очередь настроена на повторную попытку выполнения задачи до 5 раз, но задача автоматически отменяется, если весь процесс (включая повторные попытки) занимает более 5 минут.
Устранение неполадок
Включить ведение журналов Cloud Tasks
Журналы Cloud Tasks содержат полезную диагностическую информацию, например статус запроса, связанного с задачей. По умолчанию журналы Cloud Tasks отключены, поскольку они могут содержать слишком много записей. Рекомендуем включить журналы отладки, пока вы активно разрабатываете и отлаживаете функции очереди задач. Подробнее о том, как включить ведение журнала…
Права доступа IAM
При постановке задач в очередь или когда Cloud Tasks пытается вызвать функции очереди задач, могут возникать ошибки PERMISSION DENIED. Убедитесь, что в вашем проекте есть следующие привязки IAM:
Для добавления задач в очередь Cloud Tasks требуется разрешение IAM
cloudtasks.tasks.create.В примере это сервисный аккаунт по умолчанию App Engine.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
--role=roles/cloudtasks.enqueuer
Идентификатору, который используется для добавления задач в очередь в Cloud Tasks, требуется разрешение на использование сервисного аккаунта, связанного с задачей в Cloud Tasks.
В примере это сервисный аккаунт App Engine по умолчанию.
Инструкции о том, как добавить сервисный аккаунт App Engine по умолчанию в качестве пользователя сервисного аккаунта App Engine по умолчанию, можно найти в документации по Google Cloud IAM.
Идентификационные данные, используемые для запуска функции очереди задач, должны иметь разрешение
cloudfunctions.functions.invoke.В примере это сервисный аккаунт по умолчанию App Engine.
gcloud functions add-iam-policy-binding $FUNCTION_NAME \
--region=us-central1 \
--member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
--role=roles/cloudfunctions.invoker