Node.js-限制我发出的请求数量
我有一个节点应用程序,其中有一个Gremlin客户端:Node.js-限制我发出的请求数量,node.js,azure,azure-cosmosdb,async.js,Node.js,Azure,Azure Cosmosdb,Async.js,我有一个节点应用程序,其中有一个Gremlin客户端: var Gremlin = require('gremlin'); const client = Gremlin.createClient( 443, config.endpoint, { "session": false, "ssl": true, "user": `/dbs/${config.database}/colls/${config.collection}
var Gremlin = require('gremlin');
const client = Gremlin.createClient(
443,
config.endpoint,
{
"session": false,
"ssl": true,
"user": `/dbs/${config.database}/colls/${config.collection}`,
"password": config.primaryKey
}
);
然后,我调用CosmoDB,使用以下命令添加一些记录:
async.forEach(pData, function (data, innercallback) {
if (data.type == 'Full'){
client.execute("g.addV('test').property('id', \"" + data.$.id + "\")", {}, innercallback);
} else {
innercallback(null);
}
}, outercallback);
然而,在我的Azure端,每秒有400个请求的限制,随后我得到了错误:
ExceptionType : RequestRateTooLargeException
ExceptionMessage : Message: {"Errors":["Request rate is large"]}
有没有人对我如何限制每秒的请求数量有什么想法,而不必在Azure上进行扩展(因为这会花费更多:)
此外:
我试着用
async.forEachLimit(pData, 400, function (data, innercallback) {
if (data.type == 'Full'){
client.execute("g.addV('test').property('id', \"" + data.$.id + "\")", {}, innercallback);
} else {
innercallback(null);
}
}, outercallback);
但是如果继续查看RangeError:Maximum call stack size Oversed
如果它太高,否则如果我降低,我只会得到相同的请求速率太大异常
谢谢。让我们先把事情弄清楚。您没有每秒400个请求的收集,而是每秒400个RU的收集。RU代表请求单位,它们不能转换为请求 大致:
- 检索1KB文档的检索请求将花费1RU
- 对1KB文档的检索进行修改需要花费5 RU
else
情况下同步调用了innercallback
。应该是:
} else {
process.nextTick(function() {
innercallback(null)
});
}
对forEachLimit
的调用通常看起来是正确的,但您需要确保当真正触发请求时(if
block),innercallback
不会在1秒之前被调用,以保证在1秒内触发的请求不超过400个。最简单的方法是将回调执行延迟1秒:
client.execute("g.addV('test').property('id', \"" + data.$.id + "\")", {},
function(err) {
setTimeout(function() { innercallback(err); }, 1000);
});
更准确的解决方案是计算实际的请求+响应时间,并且只计算剩余1秒的时间setTimeout
作为进一步的改进,看起来您可以在执行异步操作之前过滤pData
数组,以消除if…else
,因此最终:
var pDataFull = pData.filter(function(data) => {
return data.type == 'Full';
});
async.forEachLimit(pDataFull, 400, function (data, innercallback) {
client.execute("g.addV('test').property('id', \"" + data.$.id +
"\")", {},
function(err) {
setTimeout(function() { innercallback(err); }, 1000);
}
);
}, outercallback);
forEachLimit
应该做这项工作,你能发布它的使用示例吗<代码>async.forEachLimit(pData、函数(数据、回调){显然有一个输入错误。@SergeyLapin-更新了上面的代码,我只添加了forEachLimit
和一个数字参数ah ok,理解RU。但是我不知道如何使用async.queue-我会按照链接中的示例替换for循环中的函数吗?是的,你会在回调中添加代码并设置concurre谢谢你的要求。