节点JS内存泄漏与http请求和async.eachLimit

时间:2017-02-09 14:46:53

标签: javascript node.js http memory-leaks

我制作一个脚本来检查某个域列表的状态。我使用异步来发出并行请求。我为并发尝试了几个值,并且当接近200K请求时,我总是以JS堆内存结束。

我修改了http.agent值,以避免连接中的队列但仍然泄漏内存。

我还删除了响应侦听器,以避免与不消耗响应相关的问题,基于http模块文档,响应必须与'data'事件或res.resume()一起使用,但如果没有侦听器则响应是丢弃:https://nodejs.org/api/http.html#http_class_http_clientrequest

最初域列表位于mySQL中为了使用mySql lib丢弃内存泄漏,我创建了一个随机域生成器。

这是代码:

const async = require('async');
const http = require('http');

let counter = 0;

const radomDomainListGenerator = function (){
    return [...Array(1000000)].map((_,i) => {
        let result = '';
        const length = '10';
        const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

        for (let i = length; i > 0; --i) {
            result += chars[Math.floor(Math.random() * chars.length)];
        }

        return result+='.com';
    });
};

var agent = new http.Agent;
agent.maxSockets = 1500;

setInterval(function(){
    console.log(counter);
}, 100);

const inspectDomains = function(elements) {
    async.eachLimit(
        radomDomainListGenerator(),
        1000,
        function(domainname, callback) {
            let timedOut = false;

            const options = {
                hostname: domainname,
                port: 80,
                path: '',
                agent: agent,
                method: 'HEAD',
                headers: {
                }
            };

            const req = http.request(options);

            req.on('error', (e) => {
                if (!timedOut) {
                    counter++;
                    callback();
                }
            });

            req.on('socket', function (socket) {
                socket.setTimeout(2000);
                counter++;
                socket.on('timeout', function() {
                    timedOut = true;
                    callback();
                    req.abort();
                });
            });

            req.end();
        },
        function(){
            console.log('END');
        });
};

inspectDomains();

0 个答案:

没有答案