Sunday, June 14, 2015

Load balancing in Nginx with redirect rather than proxy



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?



Answer



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.


No comments:

Post a Comment

linux - How to SSH to ec2 instance in VPC private subnet via NAT server

I have created a VPC in aws with a public subnet and a private subnet. The private subnet does not have direct access to external network. S...