Node.js套接字说明

3

我正在构建一个应用程序,将向远程API服务器发出大约一百万个调用。我能否限制连接数量,例如限制为10个?如果将最大套接字设置为10,是否可以实现这一点?

我正在尝试理解这些参数的作用:

keepAlive: false,
maxSockets: 999,
maxFreeSockets: 1

在 Node 的 http get 函数中,以下是代码示例:
var inputData = [];

for(i=1; i<=5000;i++){
    inputData.push('number' + i);
}

var options = {
    host: "localhost",
    port: 80,
    path: "/text.txt",
    keepAlive: false,
    maxSockets: 999,
    maxFreeSockets: 1
}


var limit = inputData.length;
var counter = 0;

function fetchData(number){

    return new Promise(function(resolve, reject){
        var http = require('http');

        fetch  = function(resp){
            var body = '';
            resp.on('data',function(chunk){
                body += chunk;
            })
            resp.on('end',function(){
                console.log(resp)
                resolve()
            })
            resp.on('error',function(err){
                console.log('error');
            })
        }
        var req = http.request(options, fetch);

        req.end();

    })
}



Promise.all(inputData.map(number => fetchData(number))).then(function(results) {
    console.log('finished');
    connection.end();

})
.catch(function(error) {
    console.log('there wa an error');
    console.log(error);
});

你尝试过阅读 文档 吗? - jcaron
OFC。我想了解这在现实生活中是什么意思。文档中的解释并没有告诉我太多信息。 - Adam
文档实际上非常明确。 "agent.maxSockets:默认设置为Infinity。确定代理可以针对每个源打开多少并发套接字。源可以是“host:port”或“host:port:localAddress”组合。" 那里有什么不清楚的吗?您是否有特定的情况,其中文档中描述的内容无法正常工作? - jcaron
我需要进行大约100万次API调用,并且需要限制连接数量为100个并发连接,以避免DDOS API服务器。设置此选项是否可以实现?当他们说代理时,他们是指应用程序吗?maxsockets与maxFreeSockets有何不同,如何将它们组合在一起以实现上述目标?另外,我应该更改keep alive flat吗?像上面的实现是否足够完成工作? - Adam
这些都在文档中明确说明。请注意,根据该文档,它们是 Agent 的选项,而不是 http.clientRequest 的选项。如果您不信任文档(或您的实现),请从有限数量的请求和极小值开始设置限制,并使用 netstat 监视发生的情况,然后逐渐增加值。 - jcaron
2个回答

6
您真的不希望发送1,000,000个请求,并希望maxSockets将其管理在每次100个之内。有很多原因说明这不是一个好方法。相反,您应该使用自己编写的代码来管理每次最多100个活动连接。
有多种方法可以做到这一点:
  1. 编写自己的代码,启动100个连接,每次有一个完成时,就启动下一个。
  2. 使用Bluebird的Promise.map(),它具有内置并发功能,可以管理同时正在运行的数量。
  3. 使用Async的async.mapLimit(),它具有内置并发功能,可以管理同时运行的数量。
至于自己编写此类代码,您可以像这样做:
function fetchAll() {
    var start = 1;
    var end = 1000000;
    var concurrentMax = 100;
    var concurrentCnt = 0;
    var cntr = start;
    return new Promise(function(resolve, reject) {

        // start up requests until the max concurrent requests are going
        function run() {
            while (cntr < end && concurrentCnt < concurrentMax) {
                ++concurrentCnt;
                fetchData(cntr++).then(function() {
                    --concurrentCnt;
                    run();
                }, function(err) {
                    --concurrentCnt;
                    // decide what to do with error here
                    // to continue processing more requests, call run() here
                    // to stop processing more requests, call reject(err) here
                });
            }
            if (cntr >= end && concurrentCnt === 0) {
                // all requests are done here
                resolve();
            }        
        }

        run();
    });

}

1
我决定使用async库。
这是我对此问题的完整解决方案:
var async = require('async')

var http = require('http');

var inputData = [];

for(i=1; i<=2000;i++){
    inputData.push('number' + i);
}

var options = {
    host: "o2.pl",
    path: "/static/desktop.css?v=0.0.417",
    port: 80
}

function fetchData(number, callback){

    return new Promise(function(resolve, reject){

        fetch  = function(resp){
            var body = '';
            resp.on('data',function(chunk){
                body += chunk;
            })
            process.stdout.write('.')

            callback()

            resp.on('error',function(err){
                console.log('error');
                console.log(err);

            })
        }
        var req = http.request(options, fetch);

        req.end();

    })
}

function foo(item, callback){

    return callback(false, 'foo');
}

async.mapLimit(inputData,100,fetchData,function(err, result){
    console.log('finished');
})

谢谢您的帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接