Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

chain proxy in case of error #123

Closed
temsa opened this Issue Oct 4, 2011 · 8 comments

Comments

Projects
None yet
4 participants
Contributor

temsa commented Oct 4, 2011

Something I try to do with node-http-proxy for some days now, is chaining proxies in case of error : I have multiple middle server. During a delivery, at least one server will be down for a while, so I'd like, if I get an ECONNREFUSED (or a hangup, but it happens for now in about 240s, I guess 2x 120s timeout, and I didn't get how to change this), I'd like my proxy to try another host instead of returning an error I could avoid<

I've created a first proxy, I listen to the "proxyError" event, which is fired, then I ask a second proxy to handle that request and try another equivalent host), it tries to handle the request then I have a "start" event as well for it, but it never writes to my response. My response is writable because I can write to it then call res.end().

I didn't get why for now. Is it possible to do?

Owner

indexzero commented Oct 4, 2011

Are you buffering the request? You need to be doing buffering because you will need to re-emit the data and end events so that it gets written to the second response.

Can you provide a code sample? I can probably help you quickly; if you're not familiar with event buffering it can be tricky to get right.

Contributor

temsa commented Oct 4, 2011

I haven't the code with me and my implementation is pretty naive with no buffering, just chaining 2 RoutingProxy (tried also with RoutingProxy + create a HttpProxy in case of error).

I'm not familiar with event buffering yet (or maybe; but I didn't know it is called like this), so I'll just post here an example tomorrow (it's >2:00am here) and hope for help ;)

bearnard commented Oct 6, 2011

I'm also looking into getting this working, would buffering the request cause significant performance issues?

Charlie, If you have some pointers on where to start re the event buffering that would be great.

bearnard commented Nov 6, 2011

Hi, I'm trying to do something like this:

var buffer = httpProxy.buffer(req);
var buffer2 = httpProxy.buffer(req);

var primary_backend = "10.0.0.1";
var failover_backend = "10.0.0.2";

    proxy.on('proxyError', function(err, req, res){
        proxy.proxyRequest(req, res, {
            host: failover_backend,
            port: 80,
            buffer: buffer2
        });
    });

    proxy.proxyRequest(req, res, {
        host: primary_backend,
        port: 80,  
        buffer: buffer
    }); 

});

while this works for the 1st fe hundred requests, after about 300 or so I see a whole bunch of these errors:

response.resume error: Cannot resume() closed Socket.

Clearly I'm doing something wrong.

I wonder if it would be a nice feature to have proxyRequest accept multiple backends to try.

var primary_backend = ["10.0.0.1","80]
var failover_backend = ["10.0.0.2","80]
proxy.proxyRequest(req, res, {
        backends: [primary_backend, failover_backend] 
        buffer: buffer
    }); 

or something along those lines?

So to get back to my problem, what is the correct way to go about achieving this desired "failover"?.

Bearn.

bearnard commented Jan 2, 2012

any suggestions on this?

Owner

indexzero commented Feb 12, 2012

@bearnard I'm not sure there is a workable solution here. The proxyError event may be raised after the response has been partially written to or closed.

Consider the scenario when the first backend fails midway through the response. It is impossible for the proxy to know at what point of the response the reverse proxy request errored.

My suggestion would be to pass a mock response object to proxy.proxyRequest which buffers the response into memory and when it ends then writes it back to the actualy res. This way you can discard the entirety of the data returned from the backend that failed and try all over again.

Owner

indexzero commented Mar 9, 2013

This should be fixed by #374 since the proxyError event is only raised once now.

@indexzero indexzero closed this Mar 9, 2013

Is there any workaround for this problem after 2 years?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment