【问题标题】:Spikes in execution time for cloud functions?云功能的执行时间是否会激增?
【发布时间】:2021-01-25 01:56:52
【问题描述】:

我有一个非常简单的云函数,可以将单个值写入我的实时数据库。代码在这篇文章的底部。

查看日志,我发现执行时间高度不一致。截图如下:

您可以看到它低至 3 毫秒(太棒了!),高达 579 毫秒(非常糟糕——我已经看到它达到了 1000 毫秒)。结果是在我的聊天室实现中出现了非常明显的延迟,有时消息的附加顺序与发送方式不同。 (即“1”“2”“3”被接收为“2”“3”“1”)

为什么执行时间会有如此大的差异?冷启动与热启动似乎并不适用,因为您可以看到这些调用一个接一个地直接发生。我也找不到任何记录在案的实时数据库写入/秒限制,这与 Firestore 文档的 1 写入/秒限制不同。

代码如下:

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';

admin.initializeApp();

const messagesRef = admin.database().ref('/messages/general');

export const sendMessageToChannel = functions.https.onCall(async (data, context) => {
  if (!context.auth) {
    throw new functions.https.HttpsError(
      'failed-precondition', 
      'User must be logged-in.'
    );
  }

  try {
    await messagesRef.push({
      uid: context.auth.uid,
      displayName: data.displayName,
      body: data.body
    });
  } catch (error) {
    throw new functions.https.HttpsError('aborted', error);
  }
});

编辑:两年前我见过this similar question,响应者指出任务本身的执行时间是可变的。

这里是这样吗?实时数据库的写入时间是否变化很大(变化约 330 倍,从 3 毫秒到 1000 毫秒!)?

【问题讨论】:

  • 消息ID是什么?你能展示一个存储在你的数据库中的数据的例子吗?
  • 由于 Firebase Functions 与 Google Cloud Functions 共享相同的基础架构,您是否尝试过这些 tips and best pratices 中的任何一个?他们可能会帮助您解决性能问题。还请查看documentation 以了解有关可扩展性的更多信息。从日志中我注意到你的函数执行耗时 3 毫秒,响应状态为 204,这意味着没有找到任何内容。这是你说的功能日志吗?这对你有帮助吗?
  • 当我更改函数以返回没有读取或写入 Firestore 的文字值时,执行时间下降到 ~ 5 毫秒。似乎确实是向数据库读取/写入单个简单值所需的时间。我只是不明白为什么我从客户端/代码读取/写入的内容是即时的,但是通过云功能(对于更敏感的操作)进行操作会有这种延迟。
  • 您是否尝试过指定您的cloud functions locations?如果您的云功能靠近您的数据库,您将最大限度地减少延迟
  • 这方面的文档相当稀少。我只能假设您之前执行该函数的位置 - 也许环境不再具有任何容量。我没有使用过 Cloudfunctions——但我更熟悉 AWS Lambda——即使你的函数可能是热的——它的执行上下文仍然可以在 n 次调用后移动——给出冷启动(尽管启动时间更短)。我想这就是在 Lambda 中预置并发的动机——希望 GCP 能够引入类似的东西。

标签: node.js firebase-realtime-database google-cloud-functions


【解决方案1】:

根据代码,这很难控制。
你有很多步骤:\

  1. 验证用户身份验证
  2. 将他的消息发送到集合
  3. 试图捕捉任何可能的错误

因此,您不能仅仅依靠响应时间来组织消息传递顺序。
您应该在客户端设置一个服务器端时间戳来跟踪它。

您可以使用以下解释的代码来实现此目的:

try {
    message.createdAt = firebase.firestore.FieldValue.serverTimestamp() // server-side timestamp
    ... // calls to functions
} catch(err) {
    console.log("Couldn't set timestamp or send to functions")
}

这样,您可以在发送要保存的消息之前为消息设置服务器端时间戳,这样您的用户就会看到消息何时被注册(时间戳)、保存(函数调用)和确认(发送时为 200)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 2019-12-03
    • 2019-10-22
    • 2019-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多