【问题标题】:Google Cloud Storage object finalize event triggered multiple times多次触发 Google Cloud Storage 对象 finalize 事件
【发布时间】:2019-01-28 18:52:50
【问题描述】:

场景

我有几个由 Google Cloud Storage object.finalize 事件触发的 Google Cloud Functions。为此,我使用了两个存储桶并使用“同步选项:覆盖目标位置的对象”传输作业,该作业每天将单个文件从一个源存储桶复制到目标存储桶。两个函数的源存储桶相同,目标存储桶不同。

问题

大部分时间它都按预期工作,但有时我几乎同时看到多个事件。大多数时候,我看到 2 个重复项,但一次是 3 个。我输入了日志事件有效负载,但它始终相同。

更多详情

Here is an example of multiple log entries

问题

这可能是 Google Cloud Storage 的已知问题吗?

如果不是,那么很可能我的代码有问题。

我正在使用以下项目结构:

/functions
|--/foo-code
   |--executor.js
   |--foo.sql
|--/bar-code
   |--executor.js
   |--bar.sql
|--/shared-code
   |--utils.js
|--index.js
|--package.json

index.js

let foo;
let bar;

exports.foo = (event, callback) => {
    console.log(`event ${JSON.stringify(event)}`);
    foo = foo || require(`./foo-code/executor`);
    foo.execute(event, callback);
};

exports.bar = (event, callback) => {
    console.log(`event ${JSON.stringify(event)}`);
    bar = bar || require(`./bar-code/executor`);
    bar.execute(event, callback);
};

./foo-code/executor.js

const utils = require('../shared-code/utils.js)

exports.execute = (event, callback) => {
       // run Big Query foo.sql statement
};

./bar-code/executor.js

const utils = require('../shared-code/utils.js)

exports.execute = (event, callback) => {
       // run Big Query bar.sql statement
};

最后是部署

foo 带有特定桶触发器的后台函数:

gcloud beta functions deploy foo \
                --source=https://<path_to_repo>/functions \
                --trigger-bucket=foo-destination-bucket \
                --timeout=540 \
                --memory=128MB

bar带有特定bucket触发器的后台函数:

gcloud beta functions deploy bar \
                --source=https://<path_to_repo>/functions \
                --trigger-bucket=bar-destination-bucket \
                --timeout=540 \
                --memory=128MB

在我看来,最可能的问题是由于多个部署的事实(只有 trigger-bucket 标志不同)。但奇怪的是,上述设置大部分时间都有效。

【问题讨论】:

    标签: google-cloud-storage google-cloud-functions


    【解决方案1】:

    Cloud Function 的正常行为是至少在传递事件并调用后台函数时,这意味着很少会发生虚假重复。

    为了确保您的函数在重试执行尝试时行为正确,您应该通过实现它使其具有幂等性,以便即使多次传递事件也会产生所需的结果(和副作用)。

    查看一些guidelines for making a background function idempotent的文档。

    【讨论】:

    • 是的,我同意。使函数调用幂等是 qlear 的解决方案。但在我的情况下,我需要更新 Big Query 表,我不知道是否可以检查某个进程/作业是否正在运行或几秒钟前刚刚完成。好的,我看到也许可以在事务模式下查询数据库,我的问题将得到解决。
    • 感谢您澄清可以进行多次调用。
    • 如果我理解正确,您可以使用 Stackdriver logging 或 status.state 检查作业是否已完成。
    猜你喜欢
    • 2021-08-22
    • 1970-01-01
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 2011-05-19
    • 2022-08-19
    • 2023-03-12
    相关资源
    最近更新 更多