Temporarily getting EADDRNOTAVAIL after many http.request's

2,006 views
Skip to first unread message

Jochen Brüggemann

unread,
Jan 1, 2014, 2:07:17 PM1/1/14
to nod...@googlegroups.com
Hi,

i am processing many http.request's against a local web server (Solr/localhost). After round about 30,000 successful requests http.request() returns EADDRNOTAVAIL. After 5 to 10 seconds the error vanishes and everything works fine again. The problem does obviously exist within node.js because http requests against the server from other clients (i.e. curl), at the same time while not being able to access it from node,js, work without any problem. 

There are no parallel http.request's within  node.js. Every request is only issued after the one before has been closed by res.end() and all callbacks have been called.

What could be the reason that node.js is temporarily not able to connect to the server? And what makes it "self healing" after some seconds? 

Thanks for any hint!

Jochen
 

Daniel Rinehart

unread,
Jan 1, 2014, 2:50:04 PM1/1/14
to nodejs
If connections are being closed on the client, sounds a little like the node process is cycling through connections quick enough that based on the TCP TIME-WAIT the outbound client connection hasn't been made available again. You might avoid this by reusing the same HTTP connection for multiple requests.


--
--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en
 
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Jochen Brüggemann

unread,
Jan 2, 2014, 3:15:43 AM1/2/14
to nod...@googlegroups.com
I tried to do what you suggested by creating an http.Agent at first and passing it with all http.request's. Unfortunately this had no effect. I get still temporary EADDRNOTAVAILs. This is the correct way to reuse a connection, isn't it? Any other idea out there?

Jochen Brüggemann

unread,
Jan 8, 2014, 4:08:40 AM1/8/14
to nod...@googlegroups.com
I could isolate the problem. Here is the code that can reproduce the error. Having Apache as local webserver, it breaks with EADDRNOTAVAIL on different servers with i=28223. 

When broken:

  • I cannot do a http.request to localhost for (round about) 10 seconds
  • While these 10 seconds
    • I can do "curl http://localhost"  (there is no error in Apache, it is still working like charm)
    • I can do a http.request to "www.google.com" (the error only affects request to localhost)
What is wrong here?

var http = require( "http");

function httpRequest( callback ) {
    var options = {
            host: 'localhost',
            port: 80,
            path: ''
        },
        data = "";

    http.get(options, function(resp){
        resp.on('data', function( chunk ){
            data += chunk;
        }).on("end", function() {
            callback( null, data );
        });
    }).on("error", function(e){
            callback( e );
    });
}

function loop( i, callback ) {
    if( i < 100000 ) {
        httpRequest( function( err, data ) {
            if( err ) {
                console.log( "ERROR!", i, err );
                return;
            }
            if( i % 1000 === 0 ) {
                console.log( i );
            }
            loop( i+1, callback );
        });
    } else {
        callback();
    }
}

console.log( "GO!");
loop( 0, function() {
   console.log( "READY!");
});

Jochen Brüggemann

unread,
Jan 8, 2014, 5:52:00 AM1/8/14
to nod...@googlegroups.com

I have found the solution by overwriting the default global agent. One possibility is to setmaxSockets:1:

var http = require( "http"),
    agent = new http.Agent( {maxSockets: 1} ); // <-- this is new


function httpRequest( callback ) {
    var options = {
            host: 'localhost',
            port: 80,
            path: '',

            agent: agent // <-- and this is new
        },
...

With this correction the example above works. But I still had the EADDRNOTAVAIL issue within my production code, so setting the agent to false did it finally:

var http = require( "http");

function httpRequest( callback ) {
    var options = {
            host: 'localhost',
            port: 80,
            path: '',

            agent: false // <-- here
        },
...
Reply all
Reply to author
Forward
0 new messages