5

I want to use Nginx in a bit of an unconventional way. I want to load balance between a few servers, but rather than proxy content for those servers I want to redirect to them.

That is, if a request comes into my Nginx server, it should 302 redirect to another server by randomly picking one out of an upstream block or equivalent. I don't even need the other upstream block features, such as weighting (but it wouldn't hurt to have them available if possible).

For now, I have the following config, which does what I need but is a bit ugly:

upstream boxes {
        server 127.0.0.1:46011;
        server 127.0.0.1:46012;
}

server {
        listen 46011;
        return 302 http://box11.example.com$request_uri;
}

server {
        listen 46012;
        return 302 http://box12.example.com$request_uri;
}

server {
        listen 80;
        server_name example.com;

        location / {
                proxy_pass http://boxes;
        }
}

Is there a simpler way to handle this situation without resorting to proxying to myself?

1
  • Your problem is similar to mine here – pier92 Jan 30 '17 at 16:30
5

You can get a random variable from misc module:

set_random $loc_rnd 1 10;

Then choose internal location based on it, with simple weighting:

map $loc_rnd $loc_redirect {
  1 @server1;
  2 @server1;
  ...
  8 @server2;
  9 @server2;
 10 @server2;
}

location / {
 recursive_error_pages on;
 error_page 403 = $loc_redirect;
 return 403;
}

Redirects:

location @server1 {
  internal;
  return 302 http://box11.example.com$request_uri;
}

location @server2 {
  internal;
  return 302 http://box11.example.com$request_uri;
}

Other variant: use return 302 $some_variable; (and full URLs in map) directly in "/" location.

2
  • Gross, why do you need to return an internal "forbidden" to get a random redirect? – meawoppl Jan 26 '16 at 1:03
  • 1
    You can use any return code in 4xx range. Nowadays I tend to use 412. Jumping around with error_page+return have far less surprising effects than location+if solution. – kupson Jan 26 '16 at 7:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.