# Routing based on cookies

**URL:** <https://www.ruby-forum.com/t/routing-based-on-cookies/210689>\
**Category:** NGINX\
**Created:** [August 14, 2011, 10:41pm UTC](https://www.ruby-forum.com/t/routing-based-on-cookies/210689 "2011-08-14T22:41:31Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![luislavena](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/0ea827/32.png) [@luislavena](https://www.ruby-forum.com/u/luislavena)\
**Post date:** [August 14, 2011, 10:41pm UTC](https://www.ruby-forum.com/t/routing-based-on-cookies/210689/1 "2011-08-14T22:41:31Z")

</div>

Hi guys!

I have Nginx configured as load balancer to some number of application  
servers. I need to configure Nginx in such a way that if there is  
cookie set in request (“server\_id=\<some\_number\>”), I have to forward  
this request to backend identified by \<some\_number\> - if there is no  
cookie set, every server could be chosen with equal probability to  
serve request.

So my need is something similar to functionality given by nginx  
upstream hash module. But I want to have more control of which server  
has to be chosen. It has to be exact server pointed by variable (in  
this case: cookie value) - no hash calculations.

Something like this:

upstream {  
server app-1;  
server app-2;  
server app-3;  
choose $cookie\_SERVER\_ID;  
}

When cookie “SERVER\_ID” is present in request and it is number from 1  
to 3 (which means order in server listed in config or suffix in server  
name), it should suggest that this particular request should be  
forwarded to app- server. But when there is no cookie, standard  
round-robin algorithm could be used for balancing. Also when some  
server is dead (even if it is chosen by variable from cookie) request  
should be forwarded to next live backend.

How to do this? Is writing own module (similar to upstream hash) the  
simplest idea? Or is there something more clever?

Best regards,  
Kamil

---

<div class="post-metadata">

**Author:** ![grymuz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/779978/32.png) [@grymuz](https://www.ruby-forum.com/u/grymuz)\
**Post date:** [August 15, 2011, 1:18am UTC](https://www.ruby-forum.com/t/routing-based-on-cookies/210689/2 "2011-08-15T01:18:28Z")

</div>

ngx\_lua([http://wiki.nginx.org/NginxHttpLuaModule](http://wiki.nginx.org/NginxHttpLuaModule)) should meet your need.

在 2011-08-14日的 22:40 +0200，Kamil G.写道：

---

<div class="post-metadata">

**Author:** ![grymuz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/779978/32.png) [@grymuz](https://www.ruby-forum.com/u/grymuz)\
**Post date:** [August 15, 2011, 11:04am UTC](https://www.ruby-forum.com/t/routing-based-on-cookies/210689/3 "2011-08-15T11:04:57Z")

</div>

2011/8/14 Kamil G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Hi guys!

Hi

> has to be chosen. It has to be exact server pointed by variable (in
> 
> When cookie “SERVER\_ID” is present in request and it is number from 1  
> to 3 (which means order in server listed in config or suffix in server  
> name), it should suggest that this particular request should be  
> forwarded to app- server. But when there is no cookie, standard  
> round-robin algorithm could be used for balancing. Also when some  
> server is dead (even if it is chosen by variable from cookie) request  
> should be forwarded to next live backend.
> 
> How to do this? Is writing own module (similar to upstream hash) the  
> simplest idea? Or is there something more clever?

nginx sticky module ([Google Code Archive - Long-term storage for Google Code Project Hosting.](http://code.google.com/p/nginx-sticky-module/))  
does exactly what you’re looking for.

++ Jerome

---

<div class="post-metadata">

**Author:** ![grymuz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/779978/32.png) [@grymuz](https://www.ruby-forum.com/u/grymuz)\
**Post date:** [August 15, 2011, 12:01pm UTC](https://www.ruby-forum.com/t/routing-based-on-cookies/210689/4 "2011-08-15T12:01:13Z")

</div>

2011/8/15 Jrme L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> > cookie set, every server could be chosen with equal probability to  
> > server app-1;  
> > server is dead (even if it is chosen by variable from cookie) request  
> > should be forwarded to next live backend.
> > 
> > How to do this? Is writing own module (similar to upstream hash) the  
> > simplest idea? Or is there something more clever?
> 
> nginx sticky module ([Google Code Archive - Long-term storage for Google Code Project Hosting.](http://code.google.com/p/nginx-sticky-module/))  
> does exactly what you’re looking for.

Thanks! It looks great 🙂

> ++ Jerome

Kamil

---

<div class="post-metadata">

**Author:** ![grymuz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/779978/32.png) [@grymuz](https://www.ruby-forum.com/u/grymuz)\
**Post date:** [August 15, 2011, 11:59am UTC](https://www.ruby-forum.com/t/routing-based-on-cookies/210689/5 "2011-08-15T11:59:59Z")

</div>

Hi!

On Mon, Aug 15, 2011 at 1:17 AM, leepengg [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ngx\_lua([GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/NginxHttpLuaModule)) should meet your need.

Yeah, I found this before but it looks that is not enough for me. Of  
course I can choose exact backend using lua (sth. similar to this:  
[OpenResty® - High-Concurrency Web Platform Built on Nginx + LuaJIT](http://openresty.org/#DynamicRoutingBasedOnRedis)) but if this backend  
fails to respond I have no cotrol what nginx should do next, i.e it  
will return error and not - as I wanted - try another server.

It looks that a lot of modules could be raplaced by lua scripts, but  
as far as I understand not ‘load-balancer’ modules like ip\_hash or  
upstream\_hash. Am I right?

Regards,  
Kamil
