Управление функциями


Вы можете развертывать, удалять и изменять функции с помощью команд Firebase CLI или путем установки параметров времени выполнения в исходном коде функций.

Развертывание функций

Чтобы развернуть функции, запустите эту команду Firebase CLI:

firebase deploy --only functions

По умолчанию интерфейс командной строки Firebase одновременно развертывает все функции внутри вашего источника. Если ваш проект содержит более 5 функций, мы рекомендуем вам использовать флаг --only с конкретными именами функций, чтобы развернуть только те функции, которые вы отредактировали. Такое развертывание определенных функций ускоряет процесс развертывания и помогает избежать использования квот развертывания. Например:

firebase deploy --only functions:addMessage,functions:makeUppercase

При развертывании большого количества функций вы можете превысить стандартную квоту и получить сообщения об ошибках HTTP 429 или 500. Чтобы решить эту проблему, развертывайте функции группами по 10 или меньше.

Полный список доступных команд см. в справочнике по Firebase CLI .

По умолчанию интерфейс командной строки Firebase ищет исходный код в папке functions/ . При желании вы можете организовать функции в базах кода или нескольких наборах файлов.

Удаление функций

Удалить ранее развернутые функции можно следующими способами:

  • явно в интерфейсе командной строки Firebase с помощью functions:delete
  • явно в консоли Google Cloud .
  • неявно , удалив функцию из исходного кода перед развертыванием.

Все операции удаления запрашивают подтверждение перед удалением функции из производства.

Явное удаление функции в Firebase CLI поддерживает несколько аргументов, а также группы функций и позволяет указать функцию, работающую в определенном регионе. Кроме того, вы можете отменить запрос на подтверждение.

# Delete all functions that match the specified name in all regions.
firebase functions:delete myFunction
# Delete a specified function running in a specific region.
firebase functions:delete myFunction --region us-east-1
# Delete more than one function
firebase functions:delete myFunction myOtherFunction
# Delete a specified functions group.
firebase functions:delete groupA
# Bypass the confirmation prompt.
firebase functions:delete myFunction --force

При неявном удалении функции firebase deploy анализирует ваш исходный код и удаляет из производства все функции, которые были удалены из файла.

Измените имя, регион или триггер функции.

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

Переименование функции

Чтобы переименовать функцию, создайте новую переименованную версию функции в исходном коде, а затем запустите две отдельные команды развертывания. Первая команда развертывает функцию с новым именем, а вторая команда удаляет ранее развернутую версию. Например, если у вас есть функция Node.js под названием webhook , которую вы хотите изменить на webhookNew , измените код следующим образом:

// before
const functions = require('firebase-functions');

exports.webhook = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

// after
const functions = require('firebase-functions');

exports.webhookNew = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

Затем выполните следующие команды для развертывания новой функции:

# Deploy new function called webhookNew
firebase deploy --only functions:webhookNew

# Wait until deployment is done; now both webhookNew and webhook are running

# Delete webhook
firebase functions:delete webhook

Изменение региона или регионов функции

Если вы меняете указанные регионы для функции, обрабатывающей рабочий трафик, вы можете предотвратить потерю событий, выполнив следующие действия по порядку:

  1. Переименуйте функцию и измените ее регион или регионы по желанию.
  2. Разверните переименованную функцию, в результате чего один и тот же код будет временно запущен в обоих наборах регионов.
  3. Удалить предыдущую функцию.

Например, если у вас есть функция под названием webhook , которая в настоящее время находится в области функций по умолчанию us-central1 , и вы хотите перенести ее в asia-northeast1 , вам необходимо сначала изменить исходный код, чтобы переименовать функцию и изменить регион. .

// before
const functions = require('firebase-functions');

exports.webhook = functions
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

// after
const functions = require('firebase-functions');

exports.webhookAsia = functions
    .region('asia-northeast1')
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

Затем разверните, запустив:

firebase deploy --only functions:webhookAsia

Теперь выполняются две идентичные функции: webhook работает в us-central1 и webhookAsia работает в asia-northeast1 .

Затем удалите webhook :

firebase functions:delete webhook

Теперь есть только одна функция — webhookAsia , которая работает в asia-northeast1 .

Изменение типа триггера функции

По мере того, как вы со временем разрабатываете облачные функции для развертывания Firebase, вам может потребоваться изменить тип триггера функции по разным причинам. Например, вы можете захотеть перейти от одного типа события базы данных Firebase Realtime или Cloud Firestore к другому типу.

Невозможно изменить тип события функции, просто изменив исходный код и запустив firebase deploy . Чтобы избежать ошибок, измените тип триггера функции с помощью следующей процедуры:

  1. Измените исходный код, включив в него новую функцию с желаемым типом триггера.
  2. Разверните функцию, в результате чего временно запустятся как старая, так и новая функции.
  3. Явно удалите старую функцию из производства с помощью Firebase CLI.

Например, если у вас есть функция Node.js с именем objectChanged , имеющая устаревший тип события onChange , и вы хотите изменить ее на onFinalize , сначала переименуйте функцию и отредактируйте ее, чтобы она имела тип события onFinalize .

// before
const functions = require('firebase-functions');

exports.objectChanged = functions.storage.object().onChange((object) => {
    return console.log('File name is: ', object.name);
});

// after
const functions = require('firebase-functions');

exports.objectFinalized = functions.storage.object().onFinalize((object) => {
    return console.log('File name is: ', object.name);
});

Затем выполните следующие команды, чтобы сначала создать новую функцию, прежде чем удалять старую функцию:

# Create new function objectFinalized
firebase deploy --only functions:objectFinalized

# Wait until deployment is done; now both objectChanged and objectFinalized are running

# Delete objectChanged
firebase functions:delete objectChanged

Установите параметры времени выполнения

Облачные функции для Firebase позволяют выбирать параметры среды выполнения, такие как версия среды выполнения Node.js и время ожидания для каждой функции, распределение памяти и минимальное/максимальное количество экземпляров функции.

Рекомендуется устанавливать эти параметры (за исключением версии Node.js) для объекта конфигурации внутри кода функции. Этот объект RuntimeOptions является источником достоверных сведений о параметрах времени выполнения вашей функции и переопределяет параметры, установленные любым другим методом (например, через консоль Google Cloud или интерфейс командной строки gcloud).

Если ваш рабочий процесс разработки включает ручную настройку параметров времени выполнения через консоль Google Cloud или интерфейс командной строки gcloud, и вы не хотите, чтобы эти значения переопределялись при каждом развертывании, установите для параметра preserveExternalChanges значение true . Если для этой опции установлено true , Firebase объединяет параметры времени выполнения, установленные в вашем коде, с настройками развернутой в данный момент версии вашей функции со следующим приоритетом:

  1. В коде функции задана опция: переопределить внешние изменения.
  2. В коде функции для параметра установлено значение RESET_VALUE : переопределить внешние изменения значением по умолчанию.
  3. Опция не задана в коде функции, но установлена ​​в развернутой в данный момент функции: используйте опцию, указанную в развернутой функции.

Использование параметра preserveExternalChanges: true не рекомендуется для большинства сценариев, так как ваш код больше не будет полным источником достоверности параметров времени выполнения для ваших функций. Если вы его используете, проверьте консоль Google Cloud или воспользуйтесь интерфейсом командной строки gcloud, чтобы просмотреть полную конфигурацию функции.

Установить версию Node.js

Firebase SDK для облачных функций позволяет выбирать среду выполнения Node.js. Вы можете запускать все функции проекта исключительно в среде выполнения, соответствующей одной из следующих поддерживаемых версий Node.js:

  • Node.js 20 (предварительная версия)
  • Node.js 18
  • Node.js 16
  • Node.js 14

Чтобы установить версию Node.js:

Вы можете установить версию в поле engines в файле package.json , который был создан в вашем каталоге functions/ во время инициализации. Например, чтобы использовать только версию 18, отредактируйте эту строку в package.json :

  "engines": {"node": "18"}

Если вы используете менеджер пакетов Yarn или у вас есть другие особые требования к полю engines , вместо этого вы можете установить среду выполнения Firebase SDK для облачных функций в firebase.json :

  {
    "functions": {
      "runtime": "nodejs18" // or nodejs14, nodejs16 or nodejs20
    }
  }

CLI использует значение, установленное в firebase.json а не любое значение или диапазон, которые вы устанавливаете отдельно в package.json .

Обновите среду выполнения Node.js

Чтобы обновить среду выполнения Node.js:

  1. Убедитесь, что ваш проект включен в тарифный план Blaze .
  2. Убедитесь, что вы используете Firebase CLI версии 11.18.0 или новее.
  3. Измените значение engines в файле package.json , который был создан в вашем каталоге functions/ во время инициализации. Например, если вы обновляетесь с версии 16 до версии 18, запись должна выглядеть так: "engines": {"node": "18"}
  4. При желании проверьте свои изменения с помощью Firebase Local Emulator Suite .
  5. Перераспределить все функции.

Управление поведением масштабирования

По умолчанию Cloud Functions for Firebase масштабирует количество запущенных экземпляров в зависимости от количества входящих запросов, потенциально сокращая количество экземпляров до нуля во время снижения трафика. Однако если вашему приложению требуется уменьшенная задержка и вы хотите ограничить количество холодных запусков, вы можете изменить это поведение по умолчанию, указав минимальное количество экземпляров контейнера, которые будут поддерживаться в рабочем состоянии и быть готовыми обслуживать запросы.

Аналогичным образом вы можете установить максимальное число, чтобы ограничить масштабирование экземпляров в ответ на входящие запросы. Используйте этот параметр как способ контролировать свои расходы или ограничить количество подключений к вспомогательной службе, например к базе данных.

Уменьшите количество холодных запусков

Чтобы установить минимальное количество экземпляров функции в исходном коде, используйте метод runWith . Этот метод принимает объект JSON, соответствующий интерфейсу RuntimeOptions , который определяет значение minInstances . Например, эта функция устанавливает минимум 5 экземпляров для поддержания тепла:

exports.getAutocompleteResponse = functions
    .runWith({
      // Keep 5 instances warm for this latency-critical function
      minInstances: 5,
    })
    .https.onCall((data, context) => {
      // Autocomplete a user's search term
    });

Вот некоторые вещи, которые следует учитывать при установке значения minInstances :

  • Если Cloud Functions for Firebase масштабирует ваше приложение выше настройки minInstances , у вас произойдет холодный запуск для каждого экземпляра, превышающего этот порог.
  • Холодный запуск оказывает наиболее серьезное влияние на приложения с резким трафиком. Если ваше приложение имеет резкий трафик и вы установили достаточно высокое значение minInstances , чтобы холодные запуски уменьшались при каждом увеличении трафика, вы увидите значительно уменьшенную задержку. Для приложений с постоянным трафиком холодный запуск вряд ли серьезно повлияет на производительность.
  • Установка минимального количества экземпляров может иметь смысл для производственных сред, но обычно ее следует избегать в средах тестирования. Чтобы масштабировать до нуля в тестовом проекте, но при этом уменьшить количество холодных запусков в рабочем проекте, вы можете установить minInstances на основе переменной среды FIREBASE_CONFIG :

    // Get Firebase project id from `FIREBASE_CONFIG` environment variable
    const envProjectId = JSON.parse(process.env.FIREBASE_CONFIG).projectId;
    
    exports.renderProfilePage = functions
        .runWith({
          // Keep 5 instances warm for this latency-critical function
          // in production only. Default to 0 for test projects.
          minInstances: envProjectId === "my-production-project" ? 5 : 0,
        })
        .https.onRequest((req, res) => {
          // render some html
        });
    

Ограничить максимальное количество экземпляров функции

Чтобы установить максимальное количество экземпляров в исходном коде функции, используйте метод runWith . Этот метод принимает объект JSON, соответствующий интерфейсу RuntimeOptions , который определяет значения для maxInstances . Например, эта функция устанавливает ограничение в 100 экземпляров, чтобы не перегружать гипотетическую устаревшую базу данных:

exports.mirrorOrdersToLegacyDatabase = functions
    .runWith({
      // Legacy database only supports 100 simultaneous connections
      maxInstances: 100,
    })
    .firestore.document("orders/{orderId}")
    .onWrite((change, context) => {
      // Connect to legacy database
    });

Если функция HTTP масштабируется до предела maxInstances , новые запросы ставятся в очередь на 30 секунд, а затем отклоняются с кодом ответа 429 Too Many Requests если к тому времени ни один экземпляр не доступен.

Чтобы узнать больше о рекомендациях по использованию настроек максимального количества экземпляров, ознакомьтесь с этими рекомендациями по использованию maxInstances .

Установите тайм-аут и распределение памяти

В некоторых случаях у ваших функций могут быть особые требования к длительному значению тайм-аута или большому выделению памяти. Вы можете установить эти значения либо в Google Cloud Console, либо в исходном коде функции (только Firebase).

Чтобы установить выделение памяти и тайм-аут в исходном коде функций, используйте параметр runWith , представленный в Firebase SDK для Cloud Functions 2.0.0. Этот параметр среды выполнения принимает объект JSON, соответствующий интерфейсу RuntimeOptions , который определяет значения для timeoutSeconds и memory . Например, эта функция хранения использует 1 ГБ памяти и истекает через 300 секунд:

exports.convertLargeFile = functions
    .runWith({
      // Ensure the function has enough memory and time
      // to process large files
      timeoutSeconds: 300,
      memory: "1GB",
    })
    .storage.object()
    .onFinalize((object) => {
      // Do some complicated things that take a lot of memory and time
    });

Максимальное значение timeoutSeconds540 или 9 минут. Объем памяти, предоставленный функции, соответствует процессору, выделенному для этой функции, как подробно описано в этом списке допустимых значений memory :

  • 128MB — 200 МГц
  • 256MB — 400 МГц
  • 512MB — 800 МГц
  • 1GB — 1,4 ГГц
  • 2GB — 2,4 ГГц
  • 4GB — 4,8 ГГц
  • 8GB — 4,8 ГГц

Чтобы настроить распределение памяти и тайм-аут в консоли Google Cloud:

  1. В консоли Google Cloud выберите «Облачные функции» в меню слева.
  2. Выберите функцию, щелкнув ее имя в списке функций.
  3. Нажмите значок «Редактировать» в верхнем меню.
  4. Выберите выделение памяти в раскрывающемся меню с надписью « Выделенная память» .
  5. Нажмите «Дополнительно» , чтобы отобразить дополнительные параметры, и введите количество секунд в текстовом поле «Тайм-аут» .
  6. Нажмите Сохранить , чтобы обновить функцию.