【问题标题】:Google Cloud Functions + Realtime Database extremely slowGoogle Cloud Functions + 实时数据库极慢
【发布时间】:2019-04-02 09:29:23
【问题描述】:

我正在使用 Unity 开发一款用于移动设备的多人文字游戏。我一直使用 GameSparks 作为后端,但觉得它并没有给我想要的项目控制权。环顾四周后,我决定使用 Firebase。感觉是个不错的决定,但现在我在使用数据库 + 云功能时遇到了一些严重的缓慢

游戏具有回合制模式,您可以在其中玩一局并在对手完成时收到通知。一轮通过 cloudscript 调用上传,仅包含必要的数据。然后在 cloudscript 中拼凑新的游戏状态,并更新游戏数据库条目 (activeCasualGames/{gameId})。完成后,我用一些关于游戏的基本信息更新了一个 gameInfo (activeCasualGamesInfo/{gameId}) 条目,然后发送一条云消息通知对手轮到他们了。

发送的数据只有32kb,没有对代码做复杂的改动(见下方云函数代码)。此时游戏的完整数据库条目最大约为 100kb,但从发送回合到游戏在服务器上更新并通知对手的时间从 50 秒到超过一分钟不等。在 GameSparks 上,相同的操作可能需要几秒钟。

还有其他人在使用 Firebase 时遇到这种缓慢的情况吗?我在云脚本功能中犯了一些错误,还是我应该期待的性能?游戏还有一个实时模式,我还没有开始在 Firebase 中实现它,而且由于这种滞后,我觉得它的效果不会太好

非常感谢!

exports.uploadCasualGameRound = functions.https.onCall(
  (roundUploadData, response) => {
    const roundData = JSON.parse(roundUploadData);

    const updatedGameData = JSON.parse(roundData.gameData);
    const updatedGameInfo = JSON.parse(roundData.gameInfo);

    console.log("game data object:");
    console.log(updatedGameData);

    console.log("game info:");
    console.log(updatedGameInfo);

    const gameId = updatedGameData.gameId;

    console.log("updating game with id: " + gameId);

    admin
      .database()
      .ref("/activeCasualGames/" + gameId)
      .once("value")
      .then(function(snapshot: { val: any }) {
        let game = snapshot.val();
        console.log("old game:");
        console.log(game);

        const isNewGame = (game as boolean) === true;

        if (isNewGame === false) {
          console.log("THIS IS AN EXISTING GAME!");
        } else {
          console.log("THIS IS A NEW GAME!");
        }

        // make the end state of the currently stored TurnBasedGameData the beginning state of the uploaded one (limits the upload of data and prevents timeout errors)
        if (isNewGame === true) {
          updatedGameData.gameStateRoundStart.playerOneRounds =
            updatedGameData.gameStateRoundEnd.playerOneRounds;
        } else {
          // Player one rounds are not uploaded by player two, and vice versa. Compensate for this here:
          if (updatedGameData.whoseTurn === updatedGameData.playerTwoId) {
            updatedGameData.gameStateRoundEnd.playerTwoRounds =
              game.gameStateRoundEnd.playerTwoRounds;
          } else {
            updatedGameData.gameStateRoundEnd.playerOneRounds =
              game.gameStateRoundEnd.playerOneRounds;
          }

          updatedGameData.gameStateRoundStart = game.gameStateRoundEnd;
        }

        game = updatedGameData;

        console.log("Game after update:");
        console.log(game);

        // game.lastRoundFinishedDate = Date.now();
        game.finalRoundWatchedByOtherPlayer = false;

        admin
          .database()
          .ref("/activeCasualGames/" + gameId)
          .set(game)
          .then(() => {
            updatedGameInfo.roundUploaded = true;
            return admin
              .database()
              .ref("/activeCasualGamesInfo/" + gameId)
              .set(updatedGameInfo)
              .then(() => {
               exports.sendOpponentFinishedCasualGameRoundMessage(gameId, updatedGameInfo.lastPlayer, updatedGameInfo.whoseTurn);
                return true;
              });
          });
      });
  }
);

【问题讨论】:

  • 在设计 Firebase 数据库时尽量保持扁平的层次结构不要使用嵌套结构,即使 Firebase 支持嵌套结构它也会变慢
  • 这个函数的完整代码有点难以理解。你能用更少的代码和硬编码的数据重现这个问题吗?这将允许其他人看到正在发生的一切,并可能尝试重现问题。另请查看how to create a minimal, complete, verifiable example
  • 非常感谢您的意见。我与 Firebase 支持部门取得了联系,并从他们那里得到了令人惊讶的快速回复。当我知道更多时,我会在这里写下结论。 @Shanmugam:您可能在这里有所收获。游戏数据对象非常复杂且嵌套很深,遗憾的是很难做很多事情。
  • @FrankvanPuffelen:感谢您的意见。我会看看你发布的链接!

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


【解决方案1】:

在使用 Firebase 云函数 + 实时数据库时,您必须考虑一些事项。 This 问题可能有助于解决无服务器性能问题,例如 cold start。另外,我认为代码本身可能会被重构以减少对实时数据库的调用,因为每个外部请求都可能需要时间。一些技巧是使用更多的本地存储资源(内存、浏览器缓存等)并使用一些全局变量。

【讨论】:

  • 谢谢路易斯。我之前确实读过有关冷启动的内容,并确保使用该功能几次。 50秒大约是从开始到结束的平均时间。我现在正在与 Firebase 支持人员联系,并将在此处更新我对问题的了解更多!
猜你喜欢
  • 1970-01-01
  • 2019-10-03
  • 2020-02-21
  • 2019-09-25
  • 2020-03-19
  • 2023-03-16
  • 1970-01-01
  • 2021-10-06
  • 2019-03-25
相关资源
最近更新 更多