Облачные функции Google Медленный запуск [дубликат]

Привязать событие к родительскому объекту, который уже существует:

$(document).on("click", "selector", function() {
    // Your code here
});
71
задан Frank van Puffelen 10 March 2017 в 21:11
поделиться

5 ответов

firebaser здесь

Похоже, вы испытываете так называемый холодный запуск функции.

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

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

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

58
ответ дан Frank van Puffelen 18 August 2018 в 04:15
поделиться

Я сталкиваюсь с аналогичными проблемами с облачными функциями firestore. Самым большим является производительность. Специально в случае ранних стартапов, когда вы не можете позволить своим ранним клиентам увидеть «вялые» приложения. Простая процедура генерации документации, например, дает следующее:

- Выполнение функции составило 9522 мс, завершено кодом состояния: 200

Затем: у меня была страница с условиями и условиями. С облачными функциями выполнение из-за холодного запуска займет 10-15 секунд даже порой. Затем я переместил его в приложение node.js, размещенное на контейнере appengine. Время дошло до 2-3 секунд.

Я сравнивал многие особенности mongodb с firestore, и иногда мне тоже интересно, если на этом раннем этапе моего продукта я также должен перейти в другую базу данных. Самый большой совет, который я имел в firestore, - это триггерная функциональность onCreate, onUpdate объектов документа.

https://db-engines.com/en/system/Google+Cloud+Firestore%3BMongoDB

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

3
ответ дан Mr.hands-on 18 August 2018 в 04:15
поделиться

Еще одна проблема - бесплатный план (Spark).

Как только я переключусь на платный план (Blaze в моем случае), тогда мои функции начнутся

1
ответ дан Oleksii K. 18 August 2018 в 04:15
поделиться
  • 1
    Я не думаю, что изменение плана - это то, что заставило ваши функции быстрее - мы сталкиваемся с теми же проблемами с Pay-As-You-Go. Ваши функции могут быть быстрее, потому что они чаще срабатывают. – Tomas 30 May 2018 в 23:41
  • 2
    firebaser здесь Не существует намеренной разницы в производительности холодного запуска между проектами на бесплатном и оплачиваемом плане. Они работают в одной и той же инфраструктуре с той же логикой планирования. – Frank van Puffelen 5 August 2018 в 15:04

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

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

0
ответ дан Stan Swiniarski 18 August 2018 в 04:15
поделиться
  • 1
    Мы тестируем cron-job, чтобы разбудить каждую функцию. Возможно, этот подход поможет и вам. – Jesús Fuentes 11 July 2018 в 10:30
  • 2
    hey @ JesúsFuentes Мне было просто интересно, если бы функция пробуждения работала для вас. Звучит как сумасшедшее решение: D – Alexandr 26 July 2018 в 20:55
  • 3
    Привет @Alexandr, к сожалению, у нас не было времени, чтобы сделать это еще, но это в нашем списке приоритетных приоритетов. Это должно работать теоретически. Проблема связана с функциями onCall, которые необходимо запускать из приложения Firebase. Может быть, позвонить им от клиента каждые X минут? Посмотрим. – Jesús Fuentes 27 July 2018 в 08:22
  • 4
    @Alexandr мы должны поговорить за пределами Stackoverflow? Мы могли бы помочь друг другу в новых подходах. – Jesús Fuentes 27 July 2018 в 08:44
  • 5
    @Alexandr мы еще не тестировали это «пробуждение», но мы уже развернули наши функции на europe-west1. Тем не менее, неприемлемые времена. – Jesús Fuentes 7 August 2018 в 15:49

Обновление - похоже, что многие из этих проблем могут быть решены с помощью скрытой переменной process.env.FUNCTION_NAME, как показано здесь: https://github.com/firebase/functions-samples/issues/170#issuecomment-323375462

Обновление с кодом. Например, если у вас есть следующий индексный файл:

...
exports.doSomeThing = require('./doSomeThing');
exports.doSomeThingElse = require('./doSomeThingElse');
exports.doOtherStuff = require('./doOtherStuff');
// and more.......

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

Вместо разделения ваши значения включают в себя:

if (!process.env.FUNCTION_NAME || process.env.FUNCTION_NAME === 'doSomeThing') {
  exports.doSomeThing = require('./doSomeThing');
}
if (!process.env.FUNCTION_NAME || process.env.FUNCTION_NAME === 'doSomeThingElse') {
  exports. doSomeThingElse = require('./doSomeThingElse');
}
if (!process.env.FUNCTION_NAME || process.env.FUNCTION_NAME === 'doOtherStuff') {
  exports. doOtherStuff = require('./doOtherStuff');
}

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


Это должно обеспечить гораздо более аккуратное решение, чем то, что я сделал ниже (хотя приведенное ниже объяснение по-прежнему сохраняется ).


Оригинальный ответ

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

Поскольку проект получает больше функций, глобальная область все больше загрязняется, что делает проблему еще хуже - особенно если вы раскрываете свои функции в отдельные файлы (например, используя Object.assign(exports, require('./more-functions.js')); в вашем index.js.

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

const functions = require('firebase-functions');
const admin = require('firebase-admin');
// Late initialisers for performance
let initialised = false;
let handlebars;
let fs;
let path;
let encrypt;

function init() {
  if (initialised) { return; }

  handlebars = require('handlebars');
  fs = require('fs');
  path = require('path');
  ({ encrypt } = require('../common'));
  // Maybe do some handlebars compilation here too

  initialised = true;
}

Я видел улучшения от примерно 7-8 до 2-3 лет при применении этого метода к проекту с ~ 30 функциями по 8 файлам. Это также, по-видимому, вызывает необходимость в функциях

К сожалению, это по-прежнему делает HTTP-функции едва пригодными для использования с использованием пользователя.

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

23
ответ дан Tyris 18 August 2018 в 04:15
поделиться
  • 1
    Привет, Тирис, я столкнулся с такой же проблемой во время работы, я пытаюсь реализовать ваше решение. просто пытаясь понять, кто звонит на функцию init и когда? – Adir Zoari 22 April 2018 в 07:04
  • 2
    Привет @AdirZoari, мое объяснение использования init () и т. Д., Вероятно, не самая лучшая практика; его ценность заключается в том, чтобы продемонстрировать мои выводы о основной проблеме. Вам будет гораздо лучше смотреть на скрытую переменную process.env.FUNCTION_NAME и использовать это, чтобы условно включить файлы, необходимые для этой функции. Комментарий в github.com/firebase/functions-samples/issues/… дает действительно хорошее описание этой работы! Он гарантирует, что глобальная область не загрязняется методами и включает в себя нерелевантные функции. – Tyris 23 April 2018 в 07:28
Другие вопросы по тегам:

Похожие вопросы: