【问题标题】:Stripe - API Request rate limit exceeded - Firebase Cloud FunctionsStripe - 超出 API 请求速率限制 - Firebase Cloud Functions
【发布时间】:2019-01-14 18:36:13
【问题描述】:

假设我正在创建一个 PWA(渐进式 Web 应用),用户可以在其中添加产品。 这些产品的价格从 0.01 欧元到 1.00 欧元不等。 我正在使用 Stripe 进行付款。 Stripe Order 对象不支持动态价格,动态传递,没有任何引用(外键类型)。 要接受订单,Stripe 需要参考 SKU。 就我而言,这个 SKU 将是产品价格的变化。 这意味着,要涵盖所有变体,我需要 100 个 SKU,从 1(0.01 欧元)到 100(1.00 欧元)。 因此,对于在 Stripe 中创建的每个产品,我需要在 Stripe 中创建 100 个 SKU。

我尝试插入包含 200 个产品的测试数据集,这意味着(200 个产品 + (200 x 100 SKU))= 20200 个请求。 我从 Stripe 收到了一个令人惊讶的“超出请求速率限制”错误。 创建的记录不到一半... :(

“超出请求速率限制”是问题的核心。

现在,插入过程如下(x 200):

  • 在 Firestore 中创建产品。
  • Firebase 云函数监听器:
    • 在 Firestore 中插入 OMG 新产品。好的,让我们:
    • 导入官方nodejs Stripe & Algolia 库
    • 在 Stripe 中创建产品以使其可计费
    • 使用 Promise.all 在 Stripe 中创建与产品相关的 100 个 SKU(在某些时候,我最终会遇到速率限制错误,因为我的并发云函数实例使用相同的 Stripe 键,这表示同一个 Stripe 帐户)
    • 在 Algolia 中创建产品以使其可搜索

我需要解决此 Stripe API 速率限制错误的解决方案。 我有几个解决方案:

解决方案 1:

能够在给定的时间内增加 Stripe rate API 限制。 不确定这是否可行。

解决方案 2:

能够使用不同的 Stripe 键,然后在它们上旋转,以执行管理工作,例如在 Stripe 中插入多个产品/SKU。 最终在生产中,能够以编程方式为每个用户创建 1 个 Stripe 密钥,因此每个用户都有自己的限制。 不确定这是否可行。

解决方案 3:

减慢 javascript 中的插入过程。 不知道如何执行。 此外,云函数的 javascript 执行预算/限制为 60 秒。所以我不能耽误太多。

解决方案 4:

使用 Pub/Sub (?) 或 Firestore 触发器延迟工作 例如,在 Firestore 中有一个整数,每个函数调用都会递增,并且相同的函数会监听写入以重新递增他的数字等,等等,直到第 100 个 SKU 的数字等于 100。该解决方案将按顺序排列 Stripe 中的 100 个 SKU 写入。 不确定这是否会真正减慢 API 速率限制下的工作速度。此外,这样的解决方案将花费大量资金:100 多次 Firestore 写入,以及 100 多次函数调用来执行这些写入,仅针对一种产品,这意味着 200 种产品需要 20000+/20000+。那会很贵。

解决方案 5:

在用户付款时执行即时插入。 服务器端算法,在支付请求 API 调用之后,可能如下所示:

Create order in Stripe
If error 'No such sku...' catched {
  For each SKU { // Ideally filter here SKUs to create (only those in error)
    If price not between 1 and 100 {
      continue // Bad price, not legit
    }
    Create SKU in Stripe
    If error 'Already exists' {
      continue // no creation needed for that SKU
    }
    If error 'No such product...' catched {
      If productId does not exists in Firestore {
        continue // Bad productId, not legit
      }
      Create product in Stripe
    }
    Create SKU in Stripe
  }
}
Create order in Stripe

最后一个解决方案可以完成这项工作。 但它可能会在用户执行付款时带来一些延迟,这可能会增加压力。此外,它可能会在工作时间内增加 Stripe 通话。在同一时间进行多次购买可能会导致 Stripe API 速率限制错误,尤其是在装备精良的购物车时(假设购物车中平均有 30 种产品,因此在最坏的情况下,付款期间有 30 多次 HTTPS 调用,乘以 1000 个用户 = 30000 次调用 = > 条纹错误)。对于给定的产品,这个问题可能会随着时间的推移而减少,因为一旦创建了 SKU,它就会被明确地创建。尽管如此,由于每天都会有新产品,因此在创建时具有零 SKU 的产品,问题仍然存在。

你怎么看? 您还有其他想法吗?

【问题讨论】:

  • 所以选项 #1 和选项 #2 将不起作用。 Stripe 不支持增加速率限制或使用不同的 api 键。是商家要求的。我真的很喜欢选项 #5,但您也可以轻松实现选项 #3,尽管该请求链可能至少需要大约 8.4 分钟(20200 reqs @ ~40 reqs/sec 忽略峰值)。考虑到这一点,#5 看起来是最好的选择。将所有额外数据保留在数据库中似乎也太过分了。如果你只做一次插入,那么 8.4 分钟还不错。
  • 感谢您的反馈,这有助于澄清主题

标签: google-cloud-platform google-cloud-firestore stripe-payments google-cloud-functions


【解决方案1】:

稍加调整的解决方案 3 和解决方案 5 效果最佳。

解决方案 3:您可以使用 async 模块的 forEachLimit 或队列来限制对 Stripe 的并发请求数。

解决方案 5:及时插入也是一个不错的选择,因为它不会同时给 Stripe 服务器带来太多负载。关于您在工作时间遇到相同错误的担忧,这将是非常罕见的情况,因为 Stripe API 的构建性能非常好。但是,如果您对此仍有疑问,您可以做一个在非工作时间添加 SKU 的后台流程,这将继续为您创建 SKU,而不会遇到 Stripe API 速率限制错误。

解决方案 6(修改后的解决方案 5):及时插入,但每当产品进入购物车时,还会向您的服务器创建一个额外的 API 请求,然后检查 SKU 是否存在于 Stripe 中,如果不存在则创建它在购物车付款发生之前在后台进行。

【讨论】:

  • 谢谢,鉴于您的链接,我能够找到 npmjs.com/package/limiter,这是 node.js 的通用速率限制器。这可能会有所帮助。
  • 在工作时间(待定义)的后台进程会延迟产品的索引编制(最长 24 小时)。它有一个小缺点,但它仍然是一个有效的选择。
  • 我相信在产品选择时为 SKU 插入 JIT 确实是一个值得考虑的解决方案。
  • 是的,我相信它不会给服务器带来太多负载。
【解决方案2】:

解决方案 6:

相同的想法 (JIT),但将 SKU 创建从付款时间转移到产品选择时间。每次选择产品时,尝试在 Stripe 中创建产品及其当前 SKU(价格变化)。这样,Stripe 调用应该在时间上更加分散。或者它可能会以更多的 API 调用结束,因为我们选择产品的次数多于支付的次数,因为用户可以选择和取消选择产品,所以他们可能会在他们的旅程中选择更多的产品而不是最终在购物车中支付的产品总和?

解决方案 7:

同样的想法 (JIT),但 SKU 缓存在 Algolia 或 Firebase 中,所以我可以执行“此 SKU 存在吗?”在不查询 Stripe 的情况下调用,如果在 create 调用之前执行存在测试,这应该减少 Stripe 调用(我们不会盲目调用 Stripe.skus.create())。缺点是 Firebase 和 Algolia 暴露在 Front,因此 SKU 和价格也会暴露,这是一个潜在的威胁来源,因此必须使用另一个专用且只有服务器知道的索引。

【讨论】:

    猜你喜欢
    • 2019-02-28
    • 1970-01-01
    • 2021-05-27
    • 2017-07-22
    • 2019-03-20
    • 2012-08-10
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多