3

我有一个 node.js 脚本,它从外部 Web API 中提取数据以进行本地存储。第一个请求是一个查询,它返回我需要获取更多信息的 ID 列表。对于返回的每个 ID,我从 node.js 生成一个新的 http 请求,并与服务器联系以获取数据(POST 请求)。工作完成后,我睡 3 分钟,然后重复。有时 ID 的数量是数百个。对这些返回的每个单独的 http 请求可能会返回 1kb 的数据,通常更少,因此往返时间非常短。

今天早上我收到一封来自 API 提供商的电子邮件,请求我关闭我的进程,因为我“占用了具有数百个连接的所有 API 服务器”(我实际上对此感到非常自豪,但这不是重点)。说得好,我将睡眠时间从 3 分钟增加到 30 分钟,这对他们有帮助。

关于这个问题......现在我没有设置maxSockets或任何东西,所以我相信默认值为 5。这不应该意味着我一次只能创建 5 个实时 http 请求连接吗?管理员怎么有几百?数据交付后,他们的服务器是否没有挂断连接?我不这样做吗?在我的 http 请求结束时我没有明确的断开连接,所以也许我在这里有错。那么maxSockets实际上设置了什么?

4

1 回答 1

4

抱歉,由于某种原因,我没有正确阅读您的问题

maxSockets是 http 模块将为当前进程建立的最大连接数。您可以通过从 访问它来查看您当前的设置http.globalAgent.maxSockets

您可以使用以下内容查看有关给定主机的当前连接数的一些信息:

console.log("Active socket connections: %d", http.globalAgent.sockets['localhost:8080'].length )
console.log("Total queued requests: %d", http.globalAgent.requests['localhost:8080'].length)

localhost:8080也用您提出请求的主机和端口替换。

您可以在以下两点看到节点如何处理这些连接:

添加新连接并存储到请求队列

https://github.com/joyent/node/blob/master/lib/_http_agent.js#L83

从排队的请求创建连接

https://github.com/joyent/node/blob/master/lib/_http_agent.js#L148


我很快就写了这篇文章,让您了解如何将这些请求错开一点。此特定代码不会检查有多少请求“待处理”,您可以轻松修改它以允许您在任何给定时间仅发出一定数量的请求(老实说,这将是更好的方法) .

var Stagger = function (data, stagger, fn, cb) {

    var self        = this;
    this.timerID    = 0;
    this.data       = [].concat(data);
    this.fn         = fn;
    this.cb         = cb;
    this.stagger    = stagger;
    this.iteration  = 0;
    this.store      = {};

    this.start = function () {
        (function __stagger() {

            self.fn(self.iteration, self.data[self.iteration], self.store);

            self.iteration++;

            if (self.iteration != self.data.length)
                self.timerID = setTimeout(__stagger, self.stagger);
            else
                cb(self.store);

        })();
    };

    this.stop = function () {
        clearTimeout(self.timerID);

    };
};


var t = new Stagger([1,2,3,4,5,6], 1000, function (i, item, store) {
    console.log(i, item);
    if (!store.out) store.out = [];

    store.out[i] = Math.pow(2,i);
},
function (store) {
    console.log('Done!', store);
});

t.start();

这段代码肯定可以改进,但它应该让你知道从哪里开始。

现场演示: http: //jsbin.com/ewoyik/1/edit(注意:需要控制台)

于 2013-04-17T17:24:04.223 回答