4

I need to two different sets of upstreams. But all my requests come from the same URL (same path). The difference is that some request will have a special argument and some won't. Depending on that, I would need to choose which upstream to use. Here is a incomplete part of an example of my configuration file:

  server_name localhost;

    root /var/www/something/;

  upstream pool1 
  {
    server localhost:5001;
    server localhost:5002;
    server localhost:5003;
  }


 upstream pool2
  {
    server localhost:6001;
    server localhost:6002;
    server localhost:6003;
  }


   location /
    { 
 # this is the part where I need help 
        try_files $uri @pool1;

    }

 location @pool1
    {
      include fastcgi_params;
      fastcgi_pass pool1;
    }


location @pool2
    {
      include fastcgi_params;
      fastcgi_pass pool2;
    }

So...the part I don't know is how to check if the argument/parameter is in the URL and depending on that, use either location pool1 or pool2.

Any idea how can I implement this?

Thanks!

3 Answers3

3

@hellvinz is right. I can't comment so I'm making another answer.

location / {
   if($myArg = "otherPool") {
       rewrite  ^/(.*)$ /otherUpstream/$1 last;
     } 
   try_files $uri pool1;
}

location /otherUpstream {
     proxy_pass http://@pool2;
}

I think you'll have to change $myArg to the name of the query parameter you're testing for and otherPool to whatever you set it to. Plus the rewrite is untested, so I may have that wrong too but you get the idea.

2

I like to propose an alternate version of this without if statement. I know this is an older question, but future googlers might still find this helpful.

I must admit it also means changing the way you select the upstream. But I can't see a problem in doing this.

The idea is to send a custom HTTP header (X-Server-Select) with the request. This allows nginx to then select the correct pool. If the header isn't present, a default will be selected.

Your configuration might become something like this:

upstream pool1 
{
  server localhost:5001;
  server localhost:5002;
  server localhost:5003;
}
upstream pool2
{
  server localhost:6001;
  server localhost:6002;
  server localhost:6003;
}

# map to different upstream backends based on header
map $http_x_server_select $pool {
    default "pool1";
    pool1 "pool1";
    pool2 "pool2";
}

location /
{
  include fastcgi_params;
  fastcgi_pass $pool;
}

Source: nginx use different backend based on http header

Added after coming back to this as future me: To easily test servers you can install an extension in chrome (I use ModHeader) that allows you to modify request headers.

  • This article goes step-by-step with mentioned approach: https://www.claudiokuenzler.com/blog/804/different-proxy_pass-upstream-depending-client-ip-address-nginx – ebu_sho Jan 24 '22 at 14:41
0

You can use a if testing the parameter contained by $arg

hellvinz
  • 3,046
  • 2
  • 17
  • 9
  • Hi. But such an `if` isn't only for rewrite? how can I use it inside a location to choose which pool? nginx tells me "try_files directive is not allowed here" (inside the IF). – Mariano Martinez Peck Dec 18 '13 at 15:30