【问题标题】:Google cloud functions write quota problems with 40+ functions谷歌云函数用40+函数写配额问题
【发布时间】:2020-05-26 14:53:59
【问题描述】:

我们大量使用 Google Cloud Functions(目前部署了大约 40 个功能)。它们都在一个存储库中,这是我们的 nodejs 后端的 monorepo。当合并新功能/错误修复时,它们会使用 Github Actions 进行部署。我们的问题是所有功能都已部署,我们处理并发以一次部署多个功能(多个部署并行运行)但我们碰壁了。我们正在达到写入配额(即 100 秒前 80 个请求),我们不知道为什么。似乎单个函数部署会发送大约 40 个写入请求,这是正常的,并且以较慢的方式部署函数(一次最多 2 个)是不可接受的,因为部署将花费 40 多分钟。

在搜索有关配额的信息时,我发现单个函数部署应该执行 1 个写入请求(有意义),但它对我们执行多个,我找不到任何调试方法。

用于部署的示例命令:

gcloud functions deploy functionName --runtime nodejs10 --memory=2048MB --timeout=540s --set-env-vars FN_NAME=functionName --trigger-http --allow-unauthenticated --project our-project --set-env-vars APP_ENV=production

我们的函数结构如下所示(名称已被替换):

functions/src
├── fns
│   │  
│   ├── atlas
│   │   ├── some-function.fn.ts
│   │   ├── some-function.fn.ts
│   │   ├── newsletter
│   │   │   ├── some-function.fn.ts
│   │   │   └── some-function.fn.ts
│   │   ├── suggestion
│   │   │   ├── some-function.fn.ts
│   │   │   └── some-function.fn.ts
│   │   ├── some-function.fn.ts
│   │   └── some-function.fn.ts
│   │  
│   ├── leads
│   │   ├── some-function.fn.ts
│   │   ├── some-function.fn.ts
│   │   ├── some-function.fn.ts
│   │   ├── some-function.fn.ts
│   │   ├── some-function.fn.ts
│   │   └── some-function.fn.ts
│   │  
│   ├── utils
│   │   ├── some-function.fn.ts
│   │   ├── some-function.fn.ts
│   │   ├── some-function.fn.ts
│   │   └── some-function.fn.ts
│   └── development.fn.ts
├── utils
│   ├── some-file-used-by-multiple-functions.ts
│   └── some-file-used-by-multiple-functions.ts
└── index.ts

development.fn.ts 包含仅在本地机器上运行并在部署期间被忽略的代码。它基本上启动了所有功能。

每个 .fn.ts 都导出一个以函数命名的变量,它只是一个处理请求请求的函数。这包含在我们的“引导程序”中,它处理与数据库、PubSub 客户端和其他客户端的连接。

index.ts 是 Google Cloud 的入口文件,内容如下:

import { fns, getFnDefinition } from './bootstrap/get-fns';

// should export util
const ENV_FUNCTION_NAME = process.env.FN_NAME;
const shouldExportFn = (fnName: string) => {
  if (!ENV_FUNCTION_NAME) {
    return true;
  }

  return ENV_FUNCTION_NAME === fnName;
};

// export cycle
for (const fn of fns) {
  if (shouldExportFn(fn.name)) {
    const fnDefinition = getFnDefinition(fn);
    exports[fn.name] = fnDefinition.handler;
  }
}

export default exports;

其中fns 是我们函数的{ name, absolutePath } 数组。它是从文件系统读取的(因此没有导入),getFnDefinition 需要该文件,并根据结果(导出对象)决定该函数是由 HTTP 请求还是由 PubSub 消息触发。

我还看到了--entry-point=ENTRY_POINT 选项,但我不确定这是否能解决我们的问题。如果每个函数都有自己的入口点而不是 index.js,会有所帮助吗?

【问题讨论】:

    标签: node.js google-cloud-platform google-cloud-functions


    【解决方案1】:

    问题在于您如何部署它们。您在一个 Github 存储库中拥有全部 40 个功能,但是当一个功能需要更改时,您如何部署它们?你重新同步/重新部署整个事情吗?这可以解释 40 次写入,因为您有 40 个函数。我建议将它们放在单独的 repo 中,或者确保每个单独的更新不会导致所有功能都得到更新。

    【讨论】:

    • 我们的问题在于我们部署的方式(我们部署每一个功能)。我们需要找到一个更好的解决方案,但这非常复杂,遗憾的是我们没有时间创建可以检查需要更新的内容。
    【解决方案2】:

    也遇到了这个问题,但是有 READS!仅仅部署(大约 24 个函数)大约两打次,我在几个小时内就达到了 150k READS。看来我什至必须优化我的部署策略...

    【讨论】:

      【解决方案3】:

      我们当前的解决方案有点愚蠢,但它确实有效。

      事实证明,我们达到的限制(写入配额)很容易被绕过。我们现在要做的是创建函数 deploy 的 zip,将其上传到 gcloud 存储,然后在部署期间将其作为参数传递。这意味着我们现在没有达到写入配额(因为没有上传文件)并且一切正常。但是,我们将来需要以更好的方式解决这个问题,因为部署函数时限制为 60 个,而我们目前有 48 个。

      【讨论】:

        猜你喜欢
        • 2021-03-04
        • 2018-03-01
        • 2020-04-24
        • 1970-01-01
        • 1970-01-01
        • 2019-02-15
        • 2018-12-07
        • 2018-10-02
        • 2021-01-22
        相关资源
        最近更新 更多