如何限制每个用户的API调用?漏斗算法

时间:2019-01-23 20:21:27

标签: javascript

我正在尝试限制我的应用程序上的API调用以进行购物,每个用户的调用限制为每秒2次调用。我有一个可以用来识别每个用户的域,但是我正在尝试使用一个公共节点库来做到这一点-我已经使用shopify官方npm包构建了后端而没有使用shopify官方的npm包,所以我试图通过一个节点来完成它库或使用一些手动代码,我真的不确定如何确定每个域值的限制,我对此并没有看到太多资源。

这是它的外观和使用的库:

我正在尝试使用此库:

https://www.npmjs.com/package/leaky-bucket

const LeakyBucket = require('leaky-bucket');


var bucket = new LeakyBucket({
     capacity: 2,          // items per interval, defaults to 60
     interval: 1,          // seconds, defaults to 60
     maxWaitingTime: 60
      // seconds, defaults to 300
});


var exports = module.exports = {

    getAllOrders: (req, res) => {
        const domain = req.params.domain;
        console.log(domain)
        bucket.throttle(function(domain) {
        db.getStoreTocken(domain, (result) => {
            const shopRequestUrl = 'https://' + domain + '/admin/orders.json';
            const shopRequestHeaders = { 'X-Shopify-Access-Token': result, };
            console.log(shopRequestUrl)
            console.log(result)
            request.get(shopRequestUrl, { headers: shopRequestHeaders }).then((shopResponse) => {
                res.status(200).end(shopResponse);
                console.log(shopResponse)           
            }).catch((error) => {
                res.status(error.statusCode).send(error.error.error_description);
            });     
        });
    })
    }

如您所见,我解析了该库中的域,尽管它没有提及可以识别该域的任何地方,我可以添加一些域标识符并将其与该库混合,还是我必须编写自己的代码并以某种方式做到这一点,还是只是用官方的shopify库重写该死的东西?

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您可以创建一个对象,其中包含每个域的存储桶列表:

//buckets.js
const LeakyBucket = require('leaky-bucket');

let domains = {};
module.exports = (domain) => {
  if(domains[domain]) {
    return domains[domain]
   }
   domains[domain] = new LeakyBucket({
     capacity: 2,          // items per interval, defaults to 60
     interval: 1,          // seconds, defaults to 60
     maxWaitingTime: 60
      // seconds, defaults to 300
  });
  return domains[domain];
}

通过这种方式,您可以为每个域创建存储桶,但会浪费存储桶的缓存。我不知道这是否满足您的需要,还请注意,如果您正在运行2个或更多Node.js进程,则每个进程在存储桶的内存中都会有一个副本。