Switching backends based on a cookie

saltyflorida nginx-forum at nginx.us
Wed Feb 3 08:31:21 MSK 2010


Eugaia Wrote:
-------------------------------------------------------
> saltyflorida wrote:
> > 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;
> >         }
> >     }
> > }
> >   
> Sorry, my fault.  That should have read 
> 'proxy_pass   
> htttp://backend_production/;'.  The final slash
> 'deletes' the first part 
> of the location that's passed.
> 
> Note that you will want to add the slash for the
> /production/, 
> /testing/... blocks, but not for the /wp-admin
> block.
> 
> Marcus.
> 
> 
> _______________________________________________
> nginx mailing list
> nginx at nginx.org
> http://nginx.org/mailman/listinfo/nginx

Marcus,
Thank you for the help. Sorry I did not reply sooner. Thank you
for explaining about the final slash. I tried adding the slash
in the /production/, /testing/, etc. blocks but then I got a
redirect loop. Is there something else I missed?

Eliot

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




More information about the nginx mailing list