Session affinity (sticky) with Nginx load balancing

These are instructions for setting up session affinity with Nginx web server and Plone CMS. Nginx can be used as a load balancer at the front of several Plone front-end processes (ZEO processes). By default, Nginx does not do session affinity, a.k.a. sticky sessions.  If you have site functionality which stores user specific data on the front end session data, let’s say an eCommerce site shopping cart, you must always redirect the user to the same ZEO process or they will have have different random shopping cart for each front end client.

Instructions assume you are installing Nginx via buildout.

Nginx sticky session can be loaded from here

Manually extract nginx-sticky-module under src folder:

cd src
wget http://nginx-sticky-module.googlecode.com/files/nginx-sticky-module-1.0-rc2.tar.gz

Then add it do Nginx configure options in buildout part:

[nginx-build]
recipe = zc.recipe.cmmi
url = http://sysoev.ru/nginx/nginx-0.7.65.tar.gz
extra_options = --add-module=${buildout:directory}/src/nginx-sticky-module-1.0-rc2

Now test recompling Nginx via buildout:

mv parts/nginx-build/ parts/nginx-build-old # Make sure full rebuild is done
bin/buildout install nginx-build

See that it compiles without erros. Here is the line of compiling sticky module:

gcc -c -O -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Wunused-function -Wunused-variable -Wunused-value -Werror -g   -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs -I src/http -I src/http/modules -I src/mail \
        -o objs/addon/nginx-sticky-module-1.0-rc2/ngx_http_sticky_module.o \

Now add sticky to the load balancer section of nginx config:

[balancer]
recipe = gocept.nginx
nginx = nginx-build
...
http {
        client_max_body_size 64M;
        upstream zope {
                sticky;
                server ${hosts:client1}:${ports:client1} max_fails=3 fail_timeout=30s;
                server ${hosts:client2}:${ports:client2} max_fails=3 fail_timeout=30s;
                server ${hosts:client3}:${ports:client3} max_fails=3 fail_timeout=30s;
        }

Reinstall nginx balaner configs and start-up scripts:

bin/buildout install balancer

See that generated configuration is ok:

bin/nginx-balancer configtest

Restart Nginx:

bin/nginx-balancer stop ;bin/nginx-balancer start

Check that some (non-anonymous) page has route cookie set by sticky module:

Huiske-iMac:tmp moo$ wget -S http://yoursite.com/sisalto/secret-travel-destination-infoa
--2011-03-21 21:31:40--  http://yoursite.com/sisalto/secret-travel-destination-infoa
Resolving yoursite.com (yoursite.com)... 12.12.12.12
Connecting to yoursite.com (yoursite.com)|12.12.12.12|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Server: nginx/0.7.65
  Content-Type: text/html;charset=utf-8
  Set-Cookie: route=7136de9c531fcda112f24c3f32c3f52f
  Content-Language: fi
  Expires: Sat, 1 Jan 2000 00:00:00 GMT
  Set-Cookie: I18N_LANGUAGE="fi"; Path=/
  Content-Length: 41471
  Date: Mon, 21 Mar 2011 19:31:40 GMT
  X-Varnish: 1979481774
  Age: 0
  Via: 1.1 varnish
  Connection: keep-alive

Now test it by doing manual session related activity and see that your shopping cart is not “lost”.

More info

Buy open source friendly bitcoins  Subscribe to this blog in a reader Follow me on Twitter Follow me on Facebook Follow me Google+

3 thoughts on “Session affinity (sticky) with Nginx load balancing

  1. This looks great! I have one question. Can it be used with the RPM version of nginx? Or does nginx have to be re-compiled for it to work?

  2. Thanks. I looked into it and it looks like you can rebuild the SRPMs or just build from source. Thanks for building this module. It’s exactly what I’ve been looking for these last few years. IP Hash can be a real pain when someone is behind a proxy server or satellite ISP that constantly changes their IP on them.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>