Switching backends based on a cookie

saltyflorida nginx-forum at nginx.us
Fri Jan 29 04:51:12 MSK 2010


Eugaia Wrote:
-------------------------------------------------------
> Hi,
> 
> saltyflorida wrote:
> > Is it possible to switch backend clusters of
> servers based on a cookie?
> >
> > I would like to set a cookie named "env" and do
> something like this:
> >
> >         if ($http_cookie ~* "env=testing(;|$)")
> {
> >             proxy_pass http://backend_testing;
> >         }
> >         if ($http_cookie ~* "env=staging(;|$)")
> {
> >             proxy_pass http://backend_staging;
> >         }
> >         if ($http_cookie ~*
> "env=production(;|$)") {
> >             proxy_pass
> http://backend_production;
> >         }
> >
> > However the "proxy_pass" directive is not
> allowed inside an "if". Is there another way I can
> approach this?
> >
> >   
> Take a look at the map module :
> 
> http://wiki.nginx.org/NginxHttpMapModule
> 
> One possibility would be :
> 
> http {
> 
> map  $cookie_env  $backend {
> 
>     testing      http://backend_testing;
>     staging      http://backend_staging;
>     production   http://backend_production;
> }
> 
> server {
>     ...
>     proxy_pass   $backend;
> 
> }
> 
> }
> 
> Marcus.
> 
> 
> _______________________________________________
> nginx mailing list
> nginx at nginx.org
> http://nginx.org/mailman/listinfo/nginx

Marcus, thank you for your response. The map module is very useful.
I implemented your suggestion and am now able to switch backend servers
using the cookie.

Now I have another problem: the cache is storing pages generated by
the 3 different backend clusters. Is there a way I can bypass the cache
if the cookie is set to either "testing" or "staging"?

Here is my simplified config:
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 $mybackend {
        default      http://backend_production;
        testing      http://backend_testing;
        staging      http://backend_staging;
        production   http://backend_production;
    }

    server {
        location / {
            proxy_pass $mybackend;
            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 $mybackend;
            proxy_read_timeout 300;
        }
    }
}

Thanks,
Eliot

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




More information about the nginx mailing list