20

Nginx returns 502 while the backend is restarting. How can I make nginx proxy retry N times with M seconds delay? Is there a plugin or something else?

Caleb
  • 11,813
  • 4
  • 36
  • 49
user78416
  • 301
  • 1
  • 2
  • 3

3 Answers3

9

I found that Nginx took ~2 seconds to exhaust attempts if you specified hundreds of instances of the same backend:

    server  localhost:8080 max_fails=0;
    server  localhost:8080 max_fails=0;
    server  localhost:8080 max_fails=0;
    server  localhost:8080 max_fails=0;

(.... er, repeat as required!)

Yes, a horrendous kludge - but it does add a degree of tenacity...

Even worse than that, you could use:

    server  localhost:8080 max_fails=0;     
    server  localhost:80 backup;        

Assuming Nginx is running on port 80, this would try to continually loop the request around Nginx until localhost:8080 responds. I.e. retry an infinite(?) number of times with zero seconds delay.

I'll get back to my padded cell now....

dave
  • 91
  • 1
  • 3
  • Won't the second approach result in a recursive loop and crash the server? – Seun Osewa Mar 17 '12 at 17:02
  • @SeunOsewa It does largely depend on how long it takes for the backend to respond but yeah, that's going to overflow at some point. – Oli Dec 18 '12 at 16:33
4

If your nginx installation has Lua support then you can hold on the client for some time with sleep method. The operation is non-blocking and doesn't lock the worker. Keep in mind that user can't be held infinitely as some other network related socket/firewall timeouts may occur finally.

server {
    listen 8502;
    location / {
        #25 seconds sleep
        content_by_lua_block {
             ngx.sleep(25); 
             ngx.exit(ngx.HTTP_BAD_GATEWAY);
        }
    }
}

Then in your upstream list you need to add above server as backup to hold a client.

upstream backend {
    server 127.0.0.1:3001 fail_timeout=2s; #The backend
    server 127.0.0.1:8502 backup; #Lua holding server in the event backend is restarting
}

And this should be included in your proxied location specification:

proxy_read_timeout         30;  #Value must be higher than sleep in Lua
proxy_next_upstream error timeout http_502 http_504;
gertas
  • 1,077
  • 11
  • 12
2

Closest thing I know is this project, but I never used. I know that varnish has backend checking, maybe you want to take a look on it.

coredump
  • 12,713
  • 2
  • 36
  • 56