Using memcache to set variables

Marcus Clyne maccaday at gmail.com
Fri Aug 14 16:42:23 MSD 2009


Hi,

Avleen Vig wrote:
> On Aug 12, 2009, at 6:08, Johan Bergström <johan at bergstroem.nu> wrote:
>
>> Hey,
>> On Aug 8, 2009, at 05:13 , Avleen Vig wrote:
>>
>>> I started using the geo module to direct users by IP address, this
>>> week, and really like it!
>>>
>>> It got me thinking about another thing I've been wanting to do: Direct
>>> users to different machines based on some arbitrary data. I don't want
>>> to rely just on cookies, because those can be manipulated. Here's what
>>> I was thinking, and I'm wondering if it can be done some how in nginx?
>>>
>>> The sessionid is stored in a cookie. This can't be manipulated or the
>>> users ends up not being logged in.
>>> Store the sessionid in memcache, and have the value set to the name of
>>> a location.
>>> Have nginx fetch the value for 'sessionid' from memcache, and then
>>> redirect the user internally to that location.
>>>
>>> Is this even remotely possible? I think some hardware load balancers
>>> can do it, but I'm too poor to buy one of those :-)
>>
>> We're doing something similar - through a FastCGI-app written in C - 
>> which looks up a host as key in memcached (cookie would work just as 
>> fine) and returns a backend (we have lots of different nginx 
>> backends) that the frontends proxies to. The key here is to use 
>> X-Accel-Redirect. So, in short: Yes, it's possible and delivers ~2k 
>> r/s per frontend for us. A FastCGI/whatever app written in php/python 
>> would probably work just as well, port to C when performance is needed.
>
> Hi Johan!
>
> Thus is exactly what I'm hoping to do!
> How do you use x-accel-redirect to get the name of a backend? I've 
> never used it. Do ou have any code examples? This would be really 
> perfect.
Have a look at the eval module written by Valery Kholodkov - as mentioned.

A possible setup might be:

eval $location {
    set $memcached_key   $cookie_sid;
    memcache_pass   name:11211;
}

location / {
    try_files   $location @fallback;
}


location /_/ {
    # add directives here if desired
    internal;
}


@fallback {
    [directives to generate session ID or location]
    fastcgi_pass ...
}


I've not tested this config, though, so I don't guarantee it will work, 
but something like it should work I think.  I added the /_/ location to 
avoid infinite loops in the location / {} block, though there are many 
ways you could achieve the same result ( locations returned from 
memcached would have /_/-prefixed URLs).

I think this should be quicker than passing off to fastcgi then 
accessing memcached, since there would only be one of those two 
overheads (and the overhead of sending a subrequest to memcached would 
be very slight).

Hope this is useful,

Marcus.






More information about the nginx mailing list