Introducing Rabbitbal

Inspired by Nanite, a very interesting project by Ezra Zygmuntowicz of EngineYard that uses RabbitMQ and eventmachine-based ruby amqp library by Aman Gupta, I sat down and wrote Rabbitbal, a reverse proxy for Rails (as well as other web frameworks, not necessarily limited to Ruby) on top of RabbitMQ. It’s now available on github at http://github.com/somic/rabbitbal. Rabbitbal code is based on Nanite.

Here are benefits of AMQP-based approach over traditional HTTP-based reverse proxies taken from rabbitbal README file (in no particular order) as I see them.

  1. Model where workers fetch work as fast as they can (each going at its own pace) in theory should provide more efficient load balancing than a model where proxy assigns work based on certain criteria; methods based on round robin, arbitrary weights or least connections become simply unnecessary.
  2. RabbitMQ broker implements intelligent failover out of the box - if a web server disconnects before ack'ing, the request will be automagically requeued for another server; all in all, RabbitMQ is way smarter than a bunch of low level TCP connections.
  3. Enhanced security of actual web servers - servers behind Rabbitbal do not need inbound connectivity, they only need to be able to establish an outgoing connection to RabbitMQ broker(s).
  4. Rabbitbal does not need to know IPs or have direct connectivity into its web servers (use case: Amazon EC2 without Elastic IPs)
  5. Using Duplication pattern of RabbitMQ (see Resources below), you could be reading requests and responses off of the same broker in real time (access log aggregation, double-entry book keeping, logging, bot detection)
  6. You could relatively easily have one request go to more than 1 web server
  7. Add capacity as often and as much as you like - rabbitbal won't even know
  8. By slightly readjusting mapping between queues and URIs, you could add or remove capacity per URI if needed
  9. TCP overhead savings compared with HTTP proxies (AMQP uses persistent TCP connections)

Categories: ruby |

Comments (2)

Charlie // 30 Dec 2008

This is cool.

While I recognize that it's very early, I could see this, or something like it, taking off.

What do you think of the idea of embedding the HTTP-AMQP interface into a static web server like apache or nginx - a sort of mod_amqp if you will...

Dmitriy // 30 Dec 2008

Thanks for visiting. Yeah, this is an interesting thought. Such module will definitely be quite useful.

OTOH, you can already use rabbitbal behind either Apache or Nginx - use mod_proxy in Apache or upstream and proxy_pass in Nginx. This approach could get you better compartmentalization, in theory.