Node.JS:处理服务器每分钟最大请求数的最佳方式
Node.JS: Best way to handle max requests per minute to a server
如果这个问题已经得到回答,我很抱歉,我希望我没有违反任何 SO 规则,如果是这样,我提前道歉......
我想知道处理请求限制器的最佳方式是什么?我在网上看到了很多节流阀和限速器,但我不确定它如何或是否适用于我的情况。
我正在做一堆基于数组的 [OUTGOING] 请求承诺,在服务器上我每分钟只能发出 90 个请求。我的请求承诺是由这个命令生成的:return Promise.all(array.map(request))
.
我想这样处理:
var i = 0;
return rp({
url: uri,
json: true,
}).then((data) => {
if (i <=90) {
i ++;
return data;
} else {
return i;
}
});
但我不确定这是否是一种真正有效的处理方式,另外,我还不确定如何处理时间关系...:S
在此先感谢您的帮助,抱歉我还是一个初学者...
可能每分钟只处理 90 个请求。您可以使用以下函数使用伪递归承诺:
function multiRequest(urls, maxPerMinute){
return new Promise(function(cb){
var result = [];
//iterate recursively
(function next(i){
//if finished resolve promise
if(i>=urls.length) return cb(result);
//get all requests
var requests = Promise.all(urls.slice(i,i+maxPerMinute).map(request));
//if the requests are done, add them to result
requests.then(data=>result.push(...data));
//if the requests + one minute done, conginue with next
Promise.all([
requests,
new Promise(res=>setTimeout(res,1000*60))
] ).then(_=>next(i+maxPerMinute))
})(0);
});
}
这样使用:
multiRequests(["google.com","whosebug.com"],90)
.then(([google,so])=>...);
您可以使用 setInterval
。查看文档 here.
var requestCount = 0;
setInterval(function(){
// Every 60 seconds, reset the count
requestCount = 0;
}, 60000);
// There needs to be an additional check before calling rp,
// that checks for requestCount > 90, and returns before starting the request.
rp({
url: uri,
json: true,
})
.then((data) => {
requestCount++;
return data;
});
如果请求是从不同的代码部分开始的,那么实现诸如 服务器队列 之类的东西可能会很有用,它会等待请求直到允许这样做。一般处理程序:
var fromUrl = new Map();
function Server(url, maxPerMinute){
if(fromUrl.has(url)) return fromUrl.get(url);
fromUrl.set(url,this);
this.tld = url;
this.maxPerMinute = maxPerMinute;
this.queue = [];
this.running = false;
}
Server.prototype ={
run(d){
if(this.running && !d) return;
var curr = this.queue.shift();
if(!curr){
this.running = false;
return;
}
var [url,resolve] = curr;
Promise.all([
request(this.tld + url),
new Promise(res => setTimeout(res, 1000*60/this.maxPerMinute)
]).then(([res]) => {
resolve(res);
this.run(true);
});
},
request(url){
return new Promise(res => {
this.queue.push([url,res]);
this.run();
});
}
};
module.exports = Server;
可以这样使用:
var google = new require("server")("http://google.com");
google.maxPerMinute = 90;
google.request("/api/v3/hidden/service").then(res => ...);
如果这个问题已经得到回答,我很抱歉,我希望我没有违反任何 SO 规则,如果是这样,我提前道歉...... 我想知道处理请求限制器的最佳方式是什么?我在网上看到了很多节流阀和限速器,但我不确定它如何或是否适用于我的情况。
我正在做一堆基于数组的 [OUTGOING] 请求承诺,在服务器上我每分钟只能发出 90 个请求。我的请求承诺是由这个命令生成的:return Promise.all(array.map(request))
.
我想这样处理:
var i = 0;
return rp({
url: uri,
json: true,
}).then((data) => {
if (i <=90) {
i ++;
return data;
} else {
return i;
}
});
但我不确定这是否是一种真正有效的处理方式,另外,我还不确定如何处理时间关系...:S
在此先感谢您的帮助,抱歉我还是一个初学者...
可能每分钟只处理 90 个请求。您可以使用以下函数使用伪递归承诺:
function multiRequest(urls, maxPerMinute){
return new Promise(function(cb){
var result = [];
//iterate recursively
(function next(i){
//if finished resolve promise
if(i>=urls.length) return cb(result);
//get all requests
var requests = Promise.all(urls.slice(i,i+maxPerMinute).map(request));
//if the requests are done, add them to result
requests.then(data=>result.push(...data));
//if the requests + one minute done, conginue with next
Promise.all([
requests,
new Promise(res=>setTimeout(res,1000*60))
] ).then(_=>next(i+maxPerMinute))
})(0);
});
}
这样使用:
multiRequests(["google.com","whosebug.com"],90)
.then(([google,so])=>...);
您可以使用 setInterval
。查看文档 here.
var requestCount = 0;
setInterval(function(){
// Every 60 seconds, reset the count
requestCount = 0;
}, 60000);
// There needs to be an additional check before calling rp,
// that checks for requestCount > 90, and returns before starting the request.
rp({
url: uri,
json: true,
})
.then((data) => {
requestCount++;
return data;
});
如果请求是从不同的代码部分开始的,那么实现诸如 服务器队列 之类的东西可能会很有用,它会等待请求直到允许这样做。一般处理程序:
var fromUrl = new Map();
function Server(url, maxPerMinute){
if(fromUrl.has(url)) return fromUrl.get(url);
fromUrl.set(url,this);
this.tld = url;
this.maxPerMinute = maxPerMinute;
this.queue = [];
this.running = false;
}
Server.prototype ={
run(d){
if(this.running && !d) return;
var curr = this.queue.shift();
if(!curr){
this.running = false;
return;
}
var [url,resolve] = curr;
Promise.all([
request(this.tld + url),
new Promise(res => setTimeout(res, 1000*60/this.maxPerMinute)
]).then(([res]) => {
resolve(res);
this.run(true);
});
},
request(url){
return new Promise(res => {
this.queue.push([url,res]);
this.run();
});
}
};
module.exports = Server;
可以这样使用:
var google = new require("server")("http://google.com");
google.maxPerMinute = 90;
google.request("/api/v3/hidden/service").then(res => ...);