Albert
Albert

Reputation: 1025

Serving multiple sites from varnish

I have several sites that I want to cache using the same instance of varnish.

I did setup the backend using something like:

if (req.http.host == "time.ikub.al") {
    # Process through time backend
    set req.backend_hint = timeserver;
}

if (req.http.host == "m.time.ikub.al") {
    # Process through time mobile backend
    set req.backend_hint = timemobileserver;
}

and hash method looks like:

sub vcl_hash {
    # Called after vcl_recv to create a hash value for the request. This is used as a key
    # to look up the object in Varnish.
    hash_data(req.url);
    if (req.http.host) {
       hash_data(req.http.host);
    } else {
       hash_data(server.ip);
    }
    # hash cookies for requests that have them
    if (req.http.Cookie) {
        hash_data(req.http.Cookie);
    }
}

However, I noticed that pages from mobile version where served when on desktop and vice-versa. This happened on pages with the same name, for example "Default.aspx".

As I understand the code above the hash should include the host part and this should not happen. Am I missing something, or is there some recommendation on how to handle multiple sites?

Thanx, Albert

Upvotes: 1

Views: 478

Answers (3)

Albert
Albert

Reputation: 1025

I was under impression that "redirects" were not cached...however it seems that redirects are cached and what's happening is that a redirect response from the desktop version is cached and the next client is served the cached page so it redirect him to mobile version...I moved the redirect logic to client side and things seems to work

Upvotes: 0

Rastislav Kassak
Rastislav Kassak

Reputation: 148

Do you have your varnish instance hidden behind any other reverse proxy, load balancer, https offloader or so?

It's possible any front tier could mangle Host header so this code will not execute neither first nor second condition:

# unset req.http.host or set req.http.host = "my.varnish.backend";

if (req.http.host == "time.ikub.al") {
    # Process through time backend
    set req.backend_hint = timeserver;
}

if (req.http.host == "m.time.ikub.al") {
    # Process through time mobile backend
    set req.backend_hint = timemobileserver;
}

So req.backend_hint will not come in effect and varnish could choose backend non-deterministically. At least default backend was different after various restarts and reloads for me.

Just try to check this path, maybe it helps.

Upvotes: 0

Redithion
Redithion

Reputation: 1006

I think you've partly copied the default vcl but you forgot to return (lookup);, so after executing your code, varnish executes the default code and this might cause varnish to misbehave.

Varnish vcl_hash documentaion

Upvotes: 1

Related Questions