Question

Actually my set up looks like this.

cluster.com - 192.168.0.200 (varnish/port 80)
example.com - 192.168.0.100  (apache,namebased vhost/8080 - backendname - website)
yyy.com - 192.168.0.100  (apache,namebased vhost/8080 -backendname - api)

cluster.com is the varnish server and front-end connections coming to this and rewrite to other defined back-ends (round-robin based balancing)

    backend website     {
    .host = "example.com";
    .port = "8080";

         }
    backend api     {
       .host = "yyy.com";
        .port = "8080";

      }

     director clust round-robin     {
          { .backend = api;  }
          { .backend = website;  }

          }

        sub vcl_recv    {
        set req.backend = clust;
        if (req.request)
         {
         return(pass);
         }

         }


when i hit the cluster.com , it is always going to example.com, but what i need to do is first request go to example.com second request yyy.com and so on...when i add another server (different host/different IP say 192.168.0.111/zzz.com, and a different backend) , it goes like this

first request - example.com
second request - examplee.com
third request - zzz.com


but i can change the default behavior by setting up set req.host = yyy.com and then it will      goes to
first request - yyy.com
  second request - yyy.com
   third request - zzz.com

this is something to do with the host-header forwarding to the correct back-end. how should i add that functionality to the vcl_recv ? appreciate your help on this, this is working perfectly with other servers (different servers, not with namebased vhosts)

Was it helpful?

Solution

You don't need to worry about Host headers, since varnish backend selection doesn't use it.

So, you only need a backend declaration for 192.168.0.100:8080 (since Apache will take care of named virtual hosts). NOTE: The host header in request should contain a defined Apache ServerName/ServerAlias

So if 192.168.0.111 can resolve both example.com and yyy.com but 192.168.0.100 can't resolve zzz.com , you only need to deal with backend choosing:

# As both your defined backends resolve to the same IP and port,
#you only need to define ONE backend instead of two
backend website_and_api {
  # Which resolves both example.com and yyy.com
  .host = "192.168.0.100";
  .port = "8080";
}
# The server you add later on
backend third {
  # Which resolves all example.com, yyy.com and zzz.com
  .host = "192.168.0.111";
  .port = "8080";
}

director clust round-robin {
  #Backends that resolve both example.com and yyy.com
  { .backend = website_and_api; }
  { .backend = third; }
}

sub vcl_rec {
  # Set the default backend, I'll choose two since it resolves most domains
  set req.backend = third;
  # Choose clust if the domain is appropiate
  if ( req.http.host ~ "example.com"
    || req.http.host ~ "yyy.com") {
    set req.backend = clust;
  }
  # Any return must be done below here
  # ...
}

PS: VCL edited and expanded trying to clarify a bit

This will work fine given:

  1. The client pass the correct Host header in the request (example.com|yyy.com|zzz.com)
  2. Server 192.168.0.100 is correctly set up to handle Named virtual hosting:
    • Apache resolves example.com:8080
    • Apache resolves yyy.com:8080
    • Apache gives a sensible default for 192.168.0.100:8080
  3. Server 192.168.0.111 is correctly set up to handle Named virtual hosting:
    • Apache resolves example.com:8080
    • Apache resolves yyy.com:8080
    • Apache resolves zzz.com:8080
    • Apache gives a sensible default for 192.168.0.100:8080
  4. Your VCL code don't mess received Host header (don't set it to another thing)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top