Switching backends based on a cookie

saltyflorida nginx-forum at nginx.us
Fri Jan 29 10:13:41 MSK 2010


saltyflorida Wrote:
-------------------------------------------------------
> Eugaia Wrote:
> --------------------------------------------------
> -----
> > saltyflorida wrote:
> > > I forgot to mention that I am using caching
> with
> > the HTTP Proxy module and that I only want to
> > cache responses from the production servers.
> When
> > I have the cookie set to "testing" or
> "staging",
> > I'd like to bypass the cache and talk directly
> to
> > the backend. Does this sound feasible?
> > >   
> > Sure.  Do a rewrite using your $backend
> variable
> > under the 'location /' 
> > block to one of three other blocks, which have
> the
> > different definitions 
> > of your proxy_pass, proxy_cache_valid...
> > 
> > e.g.
> > 
> > map $cookie_  $backend {
> > 
> >     default   production;
> >     test      test;
> >     ...
> > }
> > 
> > location   / {
> >     rewrite   ^(.*)$   /$backend/$1;
> > }
> > 
> > location   /production/ {
> >     proxy_pass           
> > http://backend_production;
> >     proxy_cache_valid   ...
> > }
> > 
> > location   /test/ {
> >     proxy_pass
> >     # no proxy_cache_valid
> >     ...
> > }
> > 
> > Note, you'll need some way to catch the case of
> no
> > cookie variable, so 
> > it's unwise to put $cookie_ directly in the
> > rewrite result (you'll 
> > get an infinite loop on such results).
> > 
> > Marcus.
> > 
> > _______________________________________________
> > nginx mailing list
> > nginx at nginx.org
> > http://nginx.org/mailman/listinfo/nginx
> 
> Marcus,
> Thank you for your help. I had wondered if I could
> use a rewrite, but I don't 
> understand how this works. I tried to implement
> your suggestion, but I am
> being redirected to /testing/ or /production/.
> These show up as part of the 
> URL in the browser. Also, trying to visit pages
> other than the root return a
> 404 error. Here is my configuration. Can you point
> out what I'm doing wrong?
> 
> http {
>     upstream backend_testing {
>             ip_hash;
>         server ...
>     }
>     upstream backend_staging {
>             ip_hash;
>         server ...
>     }
>     upstream backend_production {
>             ip_hash;
>         server ...
>     }
>     proxy_cache_path /mnt/nginx_cache levels=1:2
>                      keys_zone=one:100m
>                      inactive=7d max_size=10g;
>     proxy_temp_path /var/www/nginx_temp;
> 
>     map $cookie_uslnn_env $backend {
>         default      http://backend_production;
>         testing      http://backend_testing;
>         staging      http://backend_staging;
>         production   http://backend_production;
>     }
> 
>     server {
>         location / {
>             rewrite ^(.*)$ /$backend/$1;
>         }
>         location /testing/ {
>             proxy_pass http://backend_testing;
>         }
>         location /staging/ {
>             proxy_pass http://backend_staging;
>         }
>         location /production/ {
>             proxy_pass http://backend_production;
>             proxy_cache one;
>             proxy_cache_key $my_cache_key;
>             proxy_cache_valid  200 302 304 10m;
>             proxy_cache_valid  301 1h;
>             proxy_cache_valid  any 1m;
>             proxy_cache_use_stale updating error
> timeout invalid_header http_500 http_502 http_503
> http_504;
>         }
>         location /wp-admin {
>             proxy_pass http://backend_production;
>             proxy_read_timeout 300;
>         }
>     }
> }
> 
> Thanks,
> Eliot

Correction:
The configuration I tried looks like this:

http {
    upstream backend_testing {
            ip_hash;
        server ...
    }
    upstream backend_staging {
            ip_hash;
        server ...
    }
    upstream backend_production {
            ip_hash;
        server ...
    }
    proxy_cache_path /mnt/nginx_cache levels=1:2
                     keys_zone=one:100m
                     inactive=7d max_size=10g;
    proxy_temp_path /var/www/nginx_temp;

    map $cookie_uslnn_env $backend {
        default production;
        production production;
        testing testing;
        staging staging;
    }

    server {
        location / {
            rewrite ^(.*)$ /$backend/$1;
        }
        location /testing/ {
            proxy_pass http://backend_testing;
        }
        location /staging/ {
            proxy_pass http://backend_staging;
        }
        location /production/ {
            proxy_pass http://backend_production;
            proxy_cache one;
            proxy_cache_key $my_cache_key;
            proxy_cache_valid  200 302 304 10m;
            proxy_cache_valid  301 1h;
            proxy_cache_valid  any 1m;
            proxy_cache_use_stale updating error timeout invalid_header http_500 http_502 http_503 http_504;
        }
        location /wp-admin {
            proxy_pass http://backend_production;
            proxy_read_timeout 300;
        }
    }
}

Eliot

Posted at Nginx Forum: http://forum.nginx.org/read.php?2,46979,47093#msg-47093




More information about the nginx mailing list