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


Вы можете развертывать, удалять и изменять функции с помощью команд 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 поддерживает несколько аргументов, а также группы функций и позволяет указать функцию, работающую в определенном регионе. Кроме того, вы можете отменить запрос на подтверждение.

# 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 анализирует ваш исходный код и удаляет из производства все функции, которые были удалены из файла.

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

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

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

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

Node.js

// before
const {onRequest}  = require('firebase-functions/v2/https');

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

// after
const {onRequest}  = require('firebase-functions/v2/https');

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

Питон

# before
from firebase_functions import https_fn

@https_fn.on_request()
def webhook(req: https_fn.Request) -> https_fn.Response:
    return https_fn.Response("Hello world!")

# after
from firebase_functions import https_fn

@https_fn.on_request()
def webhook_new(req: https_fn.Request) -> https_fn.Response:
    return https_fn.Response("Hello world!")

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

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

# Wait until deployment is done; now both functions are running

# Delete webhook
firebase functions:delete webhook

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

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

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

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

Node.js

// before
exports.firestoreTrigger = onDocumentCreated(
  "my-collection/{docId}",
  (event) => {},
);

// after
exports.firestoreTriggerAsia = onDocumentCreated(
  {
    document: "my-collection/{docId}",
    region: "asia-northeast1",
  },
  (event) => {},
);

Обновленный код должен указывать правильный фильтр событий (в данном случае document ) вместе с регионом. Дополнительную информацию см. в разделе «Местоположения облачных функций» .

Питон

# Before
@firestore_fn.on_document_created("my-collection/{docId}")
def firestore_trigger(event):
    pass

# After
@firestore_fn.on_document_created("my-collection/{docId}",
                                  region="asia-northeast1")
def firestore_trigger_asia(event):
    pass

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

firebase deploy --only functions:firestoreTriggerAsia

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

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

firebase functions:delete firestoreTrigger

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

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

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

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

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

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

Node.js

// before
const {onObjectDeleted} = require("firebase-functions/v2/storage");

exports.objectDeleted = onObjectDeleted((event) => {
    // ...
});

// after
const {onObjectArchived} = require("firebase-functions/v2/storage");

exports.objectArchived = onObjectArchived((event) => {
    // ...
});

Питон

# before
from firebase_functions import storage_fn

@storage_fn.on_object_deleted()
def object_deleted(event):
  # ...

# after 
from firebase_functions import storage_fn

@storage_fn.on_object_archived()
def object_archived(event):
  # ...

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

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

# Wait until deployment is done; now both objectDeleted and objectArchived are running

# Delete objectDeleted
firebase functions:delete objectDeleted

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

Облачные функции для 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. Перераспределить все функции.

Установить версию Python

Firebase SDK для облачных функций версии 12.0.0 и выше позволяет выбирать среду выполнения Python. Установите версию времени выполнения в firebase.json , как показано:

  {
    "functions": {
      "runtime": "python310" // or python311
    }
  }

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

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

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

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

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

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

Разрешить одновременные запросы

В Cloud Functions for Firebase (1-го поколения) каждый экземпляр мог обрабатывать один запрос за раз, поэтому поведение масштабирования задавалось только с минимальными и максимальными настройками экземпляров. Помимо контроля количества экземпляров, в Cloud Functions for Firebase (2-го поколения) вы можете контролировать количество запросов, которые каждый экземпляр может обслуживать одновременно, с помощью параметра concurrency . Значение по умолчанию для параллелизма — 80, но вы можете установить любое целое число от 1 до 1000.

Функции с более высокими настройками параллелизма могут поглощать всплески трафика без холодного запуска, поскольку каждый экземпляр, вероятно, имеет некоторый запас. Если экземпляр настроен на обработку до 50 одновременных запросов, но в настоящее время обрабатывает только 25, он может обрабатывать всплеск дополнительных 25 запросов без необходимости холодного запуска нового экземпляра. Напротив, при настройке параллелизма всего 1 такой всплеск запросов может привести к 25 холодным запускам.

Этот упрощенный сценарий демонстрирует потенциальное повышение эффективности параллелизма. На самом деле масштабирование для оптимизации эффективности и сокращения холодных запусков с помощью параллелизма является более сложным. Параллелизм в облачных функциях для Firebase 2-го поколения поддерживается Cloud Run и соответствует правилам автоматического масштабирования экземпляра контейнера Cloud Run.

Экспериментируя с настройками более высокого параллелизма в Cloud Functions для Firebase (2-го поколения), имейте в виду следующее:

  • Более высокие настройки параллелизма могут потребовать более высокой производительности ЦП и ОЗУ для оптимальной производительности до достижения практического предела. Например, функции, выполняющей интенсивную обработку изображений или видео, может не хватать ресурсов для обработки 1000 одновременных запросов, даже если настройки ее ЦП и ОЗУ максимальны.
  • Поскольку Cloud Functions для Firebase (2-го поколения) работает на базе Cloud Run, вы также можете обратиться к руководству Google Cloud по оптимизации параллелизма .
  • Обязательно тщательно протестируйте многопараллельную обработку в тестовой среде, прежде чем переходить на многопараллельную обработку в рабочей среде.

Поддерживайте минимальное количество экземпляров в тепле

Вы можете установить минимальное количество экземпляров функции в исходном коде. Например, эта функция устанавливает минимум 5 экземпляров для поддержания тепла:

Node.js

const { onCall } = require("firebase-functions/v2/https");

exports.getAutocompleteResponse = onCall(
  {
    // Keep 5 instances warm for this latency-critical function
    minInstances: 5,
  },
  (event) => {
    // Autocomplete user’s search term
  }
);

Питон

@https_fn.on_call(min_instances=5)
def get_autocomplete_response(event: https_fn.CallableRequest) -> https_fn.Response:

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

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

    Node.js

    const functions = require('firebase-functions');
    const { defineInt, defineString } = require('firebase-functions/params');
    
    // Define some parameters
    const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
    const welcomeMessage = defineString('WELCOME_MESSAGE');
    
    // To use configured parameters inside the config for a function, provide them 
    // directly. To use them at runtime, call .value() on them.
    export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
      (req, res) => {
        res.send(`${welcomeMessage.value()}! I am a function.`);
      }
    );
    

    Питон

    MIN_INSTANCES = params.IntParam("HELLO_WORLD_MININSTANCES")
    WELCOME_MESSAGE = params.StringParam("WELCOME_MESSAGE")
    
    @https_fn.on_request(min_instances=MIN_INSTANCES.value())
    def get_autocomplete_response(event: https_fn.Request) -> https_fn.Response:
        return https_fn.Response(f"{WELCOME_MESSAGE.value()} I'm a function.")
    

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

Вы можете установить значение максимального количества экземпляров в исходном коде функции. Например, эта функция устанавливает ограничение в 100 экземпляров, чтобы не перегружать гипотетическую устаревшую базу данных:

Node.js

const { onMessagePublished } = require("firebase-functions/v2/pubsub");

exports.mirrorevents = onMessagePublished(
  { topic: "topic-name", maxInstances: 100 },
  (event) => {
    // Connect to legacy database
  }
);

Питон

@pubsub_fn.on_message_published(topic="topic-name", max_instances=100)
def mirrorevents(event: pubsub_fn.CloudEvent):
#  Connect to legacy database

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

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

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

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

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

Node.js

exports.convertLargeFile = onObjectFinalized({
  timeoutSeconds: 300,
  memory: "1GiB",
}, (event) => {
  // Do some complicated things that take a lot of memory and time
});

Питон

@storage_fn.on_object_finalized(timeout_sec=300, memory=options.MemoryOption.GB_1)
def convert_large_file(event: storage_fn.CloudEvent):
# Do some complicated things that take a lot of memory and time.

Максимальное значение таймаута в секундах — 540 или 9 минут.

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

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

Переопределить настройки ЦП по умолчанию

При выделении до 2 ГБ памяти каждая функция в Cloud Functions for Firebase (2-го поколения) по умолчанию использует один ЦП, а затем увеличивается до 2 ЦП для 4 и 8 ГБ. Обратите внимание, что это существенно отличается от поведения по умолчанию 1-го поколения , что может привести к несколько более высоким затратам на функции с низким объемом памяти, как показано в следующей таблице:

Выделенная ОЗУ ЦП по умолчанию версии 1 (частичный) ЦП версии 2 по умолчанию Увеличение цены за мс
128 МБ 1/12 1 10,5x
256 МБ 1/6 1 5,3x
512 МБ 1/3 1 2,7x
1 ГБ 7/12 1 1,6x
2 ГБ 1 1 1x
4ГБ 2 2 1x
8 ГБ 2 2 1x
16 Гб н/д 4 н/д

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

Node.js

// Turn off Firebase defaults
setGlobalOptions({ cpu: 'gcf_gen1' });

Питон

# Use 1st gen behavior
set_global_options(cpu="gcf_gen1")

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

Node.js

// Boost CPU in a function:
export const analyzeImage = onObjectFinalized({ cpu: 2 }, (event) => {
  // computer vision goes here
});

Питон

# Boost CPU in a function:
@storage_fn.on_object_finalized(cpu=2)
def analyze_image(event: storage_fn.CloudEvent):
# computer vision goes here
,


Вы можете развертывать, удалять и изменять функции с помощью команд 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 анализирует ваш исходный код и удаляет из производства все функции, которые были удалены из файла.

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

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

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

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

Node.js

// before
const {onRequest}  = require('firebase-functions/v2/https');

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

// after
const {onRequest}  = require('firebase-functions/v2/https');

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

Питон

# before
from firebase_functions import https_fn

@https_fn.on_request()
def webhook(req: https_fn.Request) -> https_fn.Response:
    return https_fn.Response("Hello world!")

# after
from firebase_functions import https_fn

@https_fn.on_request()
def webhook_new(req: https_fn.Request) -> https_fn.Response:
    return https_fn.Response("Hello world!")

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

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

# Wait until deployment is done; now both functions are running

# Delete webhook
firebase functions:delete webhook

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

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

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

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

Node.js

// before
exports.firestoreTrigger = onDocumentCreated(
  "my-collection/{docId}",
  (event) => {},
);

// after
exports.firestoreTriggerAsia = onDocumentCreated(
  {
    document: "my-collection/{docId}",
    region: "asia-northeast1",
  },
  (event) => {},
);

Обновленный код должен указывать правильный фильтр событий (в данном случае document ) вместе с регионом. Дополнительную информацию см. в разделе «Местоположения облачных функций» .

Питон

# Before
@firestore_fn.on_document_created("my-collection/{docId}")
def firestore_trigger(event):
    pass

# After
@firestore_fn.on_document_created("my-collection/{docId}",
                                  region="asia-northeast1")
def firestore_trigger_asia(event):
    pass

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

firebase deploy --only functions:firestoreTriggerAsia

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

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

firebase functions:delete firestoreTrigger

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

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

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

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

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

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

Node.js

// before
const {onObjectDeleted} = require("firebase-functions/v2/storage");

exports.objectDeleted = onObjectDeleted((event) => {
    // ...
});

// after
const {onObjectArchived} = require("firebase-functions/v2/storage");

exports.objectArchived = onObjectArchived((event) => {
    // ...
});

Питон

# before
from firebase_functions import storage_fn

@storage_fn.on_object_deleted()
def object_deleted(event):
  # ...

# after 
from firebase_functions import storage_fn

@storage_fn.on_object_archived()
def object_archived(event):
  # ...

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

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

# Wait until deployment is done; now both objectDeleted and objectArchived are running

# Delete objectDeleted
firebase functions:delete objectDeleted

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

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

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

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

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

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

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

Firebase SDK для облачных функций позволяет выбрать время выполнения Node.js. Вы можете запустить все функции в проекте исключительно в среде выполнения, соответствующей одной из этих версий Node.js: 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"}

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

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

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

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

Для обновления вашего Node.js Stime:

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

Установить версию Python

Firebase SDK для облачных функций версий 12.0.0 и выше позволяет выбирать время выполнения Python. Установите версию времени выполнения в firebase.json , как показано:

  {
    "functions": {
      "runtime": "python310" // or python311
    }
  }

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

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

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

Используя эти настройки вместе с параллелизмом для каждого экземпляра (новая во 2-м поколении), вы можете контролировать и настроить поведение масштабирования для ваших функций. Характер вашего приложения и функции определит, какие настройки наиболее экономически эффективны и приведут к наилучшей производительности.

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

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

Разрешить одновременные запросы

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

Функции с более высокими настройками параллелизма могут поглощать всплески трафика без холода, потому что каждый экземпляр, вероятно, имеет некоторый запас. Если экземпляр настроен для обработки до 50 параллельных запросов, но в настоящее время обрабатывает только 25, он может обрабатывать всплеск 25 дополнительных запросов, не требуя нового экземпляра для холодного запуска. Напротив, с настройкой параллелистики всего 1, этот всплеск запросов может привести к 25 запускам.

Этот упрощенный сценарий демонстрирует потенциальный повышение эффективности параллелизма. В действительности масштабирование поведения для оптимизации эффективности и снижения простуды начинается с параллелизма, является более сложным. Параллелизм в облачных функциях для Firebase 2 -й генерал питается за счет Cloud Run и следует за правилами Cloud Run of Container Extance .

При экспериментировании с более высокими параллельными настройками в облачных функциях для Firebase (2 -й поколение), помните следующее:

  • Настройки более высокого параллелизма могут потребовать более высокого процессора и ОЗУ для оптимальной производительности до достижения практического предела. Например, функция, которая выполняет тяжелую обработку изображений или видео, может не иметь ресурсов для обработки 1000 параллельных запросов, даже если настройки процессора и оперативной памяти максимизируются.
  • Поскольку облачные функции для Firebase (2 -й Gen) питаются на основе Cloud Run, вы также можете ссылаться на руководство Google Cloud для оптимизации параллелизма .
  • Обязательно тщательно протестируйте многоценаровну в тестовой среде, прежде чем переключиться на многоконкурентность в производстве.

Держите минимальное количество случаев в теплом

Вы можете установить минимальное количество экземпляров для функции в исходном коде. Например, эта функция устанавливает минимум 5 экземпляров, чтобы согреться:

Node.js

const { onCall } = require("firebase-functions/v2/https");

exports.getAutocompleteResponse = onCall(
  {
    // Keep 5 instances warm for this latency-critical function
    minInstances: 5,
  },
  (event) => {
    // Autocomplete user’s search term
  }
);

Питон

@https_fn.on_call(min_instances=5)
def get_autocomplete_response(event: https_fn.CallableRequest) -> https_fn.Response:

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

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

    Node.js

    const functions = require('firebase-functions');
    const { defineInt, defineString } = require('firebase-functions/params');
    
    // Define some parameters
    const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
    const welcomeMessage = defineString('WELCOME_MESSAGE');
    
    // To use configured parameters inside the config for a function, provide them 
    // directly. To use them at runtime, call .value() on them.
    export const helloWorld = functions.runWith({ minInstances: minInstancesConfig}).https.onRequest(
      (req, res) => {
        res.send(`${welcomeMessage.value()}! I am a function.`);
      }
    );
    

    Питон

    MIN_INSTANCES = params.IntParam("HELLO_WORLD_MININSTANCES")
    WELCOME_MESSAGE = params.StringParam("WELCOME_MESSAGE")
    
    @https_fn.on_request(min_instances=MIN_INSTANCES.value())
    def get_autocomplete_response(event: https_fn.Request) -> https_fn.Response:
        return https_fn.Response(f"{WELCOME_MESSAGE.value()} I'm a function.")
    

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

Вы можете установить значение для максимальных случаев в исходном коде функции. Например, эта функция устанавливает предел в 100 экземпляров, чтобы не перегружать гипотетическую базу данных Legacy:

Node.js

const { onMessagePublished } = require("firebase-functions/v2/pubsub");

exports.mirrorevents = onMessagePublished(
  { topic: "topic-name", maxInstances: 100 },
  (event) => {
    // Connect to legacy database
  }
);

Питон

@pubsub_fn.on_message_published(topic="topic-name", max_instances=100)
def mirrorevents(event: pubsub_fn.CloudEvent):
#  Connect to legacy database

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

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

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

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

Чтобы установить распределение памяти и тайм -аут в исходном коде функций, используйте глобальные параметры для памяти и секунд тайм -аута, чтобы настроить виртуальную машину, выполняющую ваши функции. Например, эта функция облачного хранилища использует 1gib памяти и время от времени через 300 секунд:

Node.js

exports.convertLargeFile = onObjectFinalized({
  timeoutSeconds: 300,
  memory: "1GiB",
}, (event) => {
  // Do some complicated things that take a lot of memory and time
});

Питон

@storage_fn.on_object_finalized(timeout_sec=300, memory=options.MemoryOption.GB_1)
def convert_large_file(event: storage_fn.CloudEvent):
# Do some complicated things that take a lot of memory and time.

Максимальное значение для секунд времени ожидания составляет 540 или 9 минут.

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

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

Переопределить дефолт процессора

До 2 ГБ памяти распределяется, каждая функция в облачной функции для огненной базы (2 -го поколения) по умолчанию к одному процессору, а затем увеличивается до 2 ЦП для 4 и 8 ГБ. Обратите внимание, что это значительно отличается от поведения 1-го поколения по умолчанию способами, которые могут привести к немного более высоким затратам на функции с низкой памяти, как это выражено в следующей таблице:

ОЗУ выделен Версия 1 ЦП по умолчанию (дробный) Версия 2 по умолчанию процессор Повышение цен на мс
128 МБ 1/12 1 10,5x
256 МБ 1/6 1 5,3x
512 МБ 1/3 1 2.7x
1 ГБ 7/12 1 1,6x
2 ГБ 1 1 1x
4ГБ 2 2 1x
8 ГБ 2 2 1x
16 Гб н/д 4 н/д

Если вы предпочитаете поведение 1 -го поколения для ваших функций 2 -го поколения, установите по умолчанию 1 -го поколения как глобальный вариант:

Node.js

// Turn off Firebase defaults
setGlobalOptions({ cpu: 'gcf_gen1' });

Питон

# Use 1st gen behavior
set_global_options(cpu="gcf_gen1")

Для функций интенсивного процессора 2-й генерал обеспечивает гибкость для настройки дополнительного процессора. Вы можете повысить процессор на основе функции, как показано:

Node.js

// Boost CPU in a function:
export const analyzeImage = onObjectFinalized({ cpu: 2 }, (event) => {
  // computer vision goes here
});

Питон

# Boost CPU in a function:
@storage_fn.on_object_finalized(cpu=2)
def analyze_image(event: storage_fn.CloudEvent):
# computer vision goes here