条带-超出了API请求速率限制-Firebase云功能

时间:2018-08-07 15:42:17

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

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

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

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

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

  • 在Firestore中创建产品。
  • Firebase云功能侦听器:
    • OMG新产品已插入Firestore。好吧:
    • 导入官方的nodejs Stripe&Algolia库
    • 在Stripe中创建产品以使其可计费
    • 使用Promise.all在Stripe中创建与该产品相关的100 SKU(在某些时候,由于某些并发云函数实例使用相同的Stripe密钥,所以最终会出现速率限制错误。表示相同的Stripe帐户)
    • 在阿尔及利亚创建产品以使其可搜索

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

解决方案1:

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

解决方案2:

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

解决方案3:

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

解决方案4:

使用发布/订阅(?)或Firestore触发器进行延迟工作 例如,在Firestore中有一个整数,表示每个函数调用都会递增,并且同一函数会监听写入内容以重新递增其编号等,等等,等等,直到第100个SKU的编号等于100。该解决方案将按条带化顺序写入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为零的产品仍然存在问题。

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

2 个答案:

答案 0 :(得分:0)

解决方案3和解决方案5进行一些调整后效果最佳。

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

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

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

答案 1 :(得分:0)

解决方案6:

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

解决方案7:

相同的想法(JIT),但SKU缓存在Algolia或Firebase中,因此我可以执行“此SKU是否存在?”调用而无需查询Stripe,如果在create调用之前执行了存在性测试(我们不会盲目调用Stripe.skus.create()),这将减少Stripe调用。缺点是,Firebase和Algolia暴露在前端,因此SKU和价格也将存在,这是潜在的威胁来源,因此必须使用服务器专用的唯一索引。