试图了解/改善云功能冷启动的原因

时间:2020-05-04 14:27:36

标签: typescript firebase google-cloud-functions

我正在使用Firebase云功能,并在撰写本文时了解它们的最新依赖关系和节点版本:

"engines": {
   "node": "10"
},
"dependencies": {
   "firebase-admin": "8.11.0",
   "firebase-functions": "3.6.1"
}

我没有使用任何外部软件包,只有1个功能仅使用Firebase自己的服务,但是接收到的冷启动时间为9-15秒(从Firebase日志中获取的时间),我真的不确定为什么。此外,从测试中我看到以下行为:我调用函数,它以11s延迟开始。过了一段时间(不到一分钟),我以9s的延迟开始再次调用它,只有在第3次或更多次调用时,我才开始看到正常的启动时间为500ms-600ms

下面是我所讨论的功能,我很想听听有关改善冷启动的任何建议或想法(功能以打字稿写成)

index.ts

import admin from 'firebase-admin';

admin.initializeApp();

exports.createCharacter = require('./api/createCharacter');

下面是我的主要功能,乍一看似乎很冗长,但据我所知,它并没有做任何疯狂的事情。它的依赖项validCreateCharacter是一个基本函数,很少有if条语句来检查字符串的长度并确保输入对象具有必填字段,如果有问题,它将引发firebases http错误。

api / createCharacter.ts

import { CreateCharacter } from '$types/functions';
import { auth, firestore } from 'firebase-admin';
import { https } from 'firebase-functions';
import { validCreateCharacter } from '../util/validation';

/**
 * Function
 */
async function createCharacter(
  input: CreateCharacter['input'],
  context: https.CallableContext
): Promise<CreateCharacter['output']> {
  const uid = context?.auth?.uid;

  if (!uid) {
    throw new https.HttpsError('unauthenticated', 'Authentication required');
  }

  try {
    validCreateCharacter(input);

    const { username } = input;
    const characterRef = firestore().doc(`characters/${uid}`);
    const characterSecretRef = firestore().doc(`characters/${uid}/secret/${uid}`);
    const usernameRef = firestore().doc(`usernames/${username}`);

    const characterData = input;
    const characterSecretData = { gold: 1000, items: [] };

    const batch = firestore().batch();
    batch.create(characterRef, characterData);
    batch.create(characterSecretRef, characterSecretData);
    batch.create(usernameRef, { uid });

    try {
      await batch.commit();
      await auth().setCustomUserClaims(uid, { character: true });
    } catch {
      throw new https.HttpsError('already-exists', 'Username is taken');
    }

    return true;
  } catch (error) {
    throw new https.HttpsError('unknown', error?.message);
  }
}

/**
 * Export
 */
module.exports = runWith({ timeoutSeconds: 15, memory: "128MB" }).region('europe-west2').https.onCall(createCharacter);

1 个答案:

答案 0 :(得分:1)

由于云功能是无状态的,因此执行环境通常是从头开始初始化的,因此您会看到冷启动。回顾Tips & Tricks For Cloud Functions可能会有所帮助。另外,您可能想看一下Firebase团队制作的有关Minimizing Cold Start Time的内容丰富的视频,该视频基本上说明了如何最大程度地减少函数在全局范围内对所有直接或间接导入的代码执行的工作量,是最小化冷启动的关键。

您也可以尝试定期ping通此功能,以最大程度地缩短冷启动时间。 This Page可能会对此有所帮助,但这有点过时了,因此您可能需要做一些进一步的研究,以找出立即执行此操作的最佳方法。

但是,如果冷启动难以忍受,则您可能需要考虑使用App Engine之类的东西来运行自己的服务器实例。