<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fubaredness Is Contagious &#187; rabbitmq</title>
	<atom:link href="http://somic.org/category/rabbitmq/feed/" rel="self" type="application/rss+xml" />
	<link>http://somic.org</link>
	<description>Dmitriy Samovskiy's Blog</description>
	<lastBuildDate>Wed, 01 Sep 2010 07:55:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Hacking RabbitMQ &#8211; Remote Queue Forwarders</title>
		<link>http://somic.org/2009/12/02/hacking-rabbitmq-remote-queue-forwarders/</link>
		<comments>http://somic.org/2009/12/02/hacking-rabbitmq-remote-queue-forwarders/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 16:59:53 +0000</pubDate>
		<dc:creator>Dmitriy</dc:creator>
				<category><![CDATA[erlang]]></category>
		<category><![CDATA[rabbitmq]]></category>
		<category><![CDATA[hack]]></category>

		<guid isPermaLink="false">http://somic.org/?p=908</guid>
		<description><![CDATA[Since earlier this year when I got my copy of Erlang book, I&#8217;ve wanted to do something unconventional with RabbitMQ source. I finally came up with an idea, which is somewhat interesting and maybe even useful, and could be done by an Erlang beginner like myself.
Some background first. Each Erlang program in general consists of [...]]]></description>
			<content:encoded><![CDATA[<p>Since earlier this year when I got my copy of Erlang book, I&#8217;ve wanted to do something unconventional with <a href="http://www.rabbitmq.com">RabbitMQ</a> source. I finally came up with an idea, which is somewhat interesting and maybe even useful, and could be done by an Erlang beginner like myself.</p>
<p>Some background first. Each Erlang program in general consists of multiple Erlang processes that send and receive messages to/from each other. These are not your regular processes &#8211; these processes are running inside the Erlang VM, and are not mapped to either processes or threads on the system level in any way. They are cheap to create, and communications between them are fast. Each process has a process ID (pid) associated with it. If multiple Erlang VMs share a cookie (a piece of text which is used as a security token), processes on any Erlang VM can freely talk to each other without any code modification.</p>
<p>RabbitMQ implements each queue as an Erlang process. You can think of AMQP exchanges as pieces of routing logic &#8211; when a message arrives, Rabbit applies the routing rules to its routing key and sends the message to all eligible queues. Since each queue is a process and has a pid, in a nutshell exchanges send the message to several pids.</p>
<p>In non-clustered mode, Rabbit routing function will return a list of local PIDs by selecting values stored in a mnesia table (rabbit_durable_queue and rabbit_queue). But since RabbitMQ can also run in clustered mode, developers already implemented a way to send messages to queues on remote nodes. So when I hacked rabbit_durable_queue and rabbit_queue tables and replaced PIDs pointing to local queues with PIDs pointing to remote queues, I got myself a remote queue forwarder.</p>
<p>How is this useful you might ask. RabbitMQ supports remote queues only in clustered mode. The way clustering is implemented today (using mnesia in distributed mode), it&#8217;s not recommended to run a rabbit cluster over non-LAN links. This is because if 2 rabbit nodes lose and then regain connectivity to each other, the cluster may enter a &#8220;partitioned network&#8221; state, which effectively means that rabbit cluster is not functional (in other words, mnesia sacrifices tolerance to partitioning in order to achieve consistency and availability &#8211; recall CAP theorem). With remote queue forwarding, you don&#8217;t need to set up clustering and hence &#8220;partitioned network&#8221; state won&#8217;t affect you by design &#8211; and that&#8217;s what mattered to me.</p>
<p>On the other hand, remote queue forwarding can potentially break some AMQP guarantees. For example, if a remote node is temporarily unavailable, Rabbit won&#8217;t queue the message for later re-delivery (because such situation is currently impossible in unhacked Rabbit). It means that YOU SHOULD NOT USE THIS HACK UNLESS YOU KNOW WHAT YOU ARE DOING.</p>
<p>The hack works for me though in the following scenario. I publish messages with immediate=true (indicates that payload is time sensitive). Messages are sent to N local queues. These N local queues are forwarded to N remote nodes, with a consumer attached to 127.0.0.1 on each node. In this project, I don&#8217;t rely on any AMQP guarantees &#8211; I discard basic.return commands and can tolerate occasional message not reaching some or even all consumers.</p>
<p>I doubt anyone will find this hack in its current form useful, but just in case I uploaded it to <a href="http://github.com/somic/rabbit_queue_forwarder">http://github.com/somic/rabbit_queue_forwarder</a>.</p>
<p><em>PS. After I started this small project, Tony Garnock-Jones <a href="http://twitter.com/leastfixedpoint/status/5984842386">announced</a> that his work on pluggable exchange types has been added to default branch. I still went ahead and published my post, but please note that pluggable exchange types could probably achieve similar effect more cleanly.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://somic.org/2009/12/02/hacking-rabbitmq-remote-queue-forwarders/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Erlang R13B02-1</title>
		<link>http://somic.org/2009/10/21/building-erlang-r13b02-1/</link>
		<comments>http://somic.org/2009/10/21/building-erlang-r13b02-1/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 18:10:46 +0000</pubDate>
		<dc:creator>Dmitriy</dc:creator>
				<category><![CDATA[erlang]]></category>
		<category><![CDATA[rabbitmq]]></category>

		<guid isPermaLink="false">http://somic.org/?p=885</guid>
		<description><![CDATA[This is a quick note in case anyone is having the same issue.
When building erlang R13B02-1 on a 64bit non-SMP machine (not sure if it matters), &#8220;make -j 2&#8243; somehow resulted in an error which I could not work around. Reverting to simply make (without -j 2) and starting compilation from the very beginning fixed [...]]]></description>
			<content:encoded><![CDATA[<p>This is a quick note in case anyone is having the same issue.</p>
<p>When building erlang R13B02-1 on a 64bit non-SMP machine (not sure if it matters), &#8220;make -j 2&#8243; somehow resulted in an error which I could not work around. Reverting to simply make (without -j 2) and starting compilation from the very beginning fixed it.</p>
<p>Also, after final make install, I could not start erl &#8211; it was complaining about &#8220;start.boot not found&#8221;. The solution is to symlink boot files like this:</p>
<p><code style="font-size:12px"><br />
cd /usr/lib/erlang/bin<br />
ln -s /usr/lib/erlang/releases/R13B02/start.boot .<br />
ln -s /usr/lib/erlang/releases/R13B02/start_clean.boot .<br />
ln -s /usr/lib/erlang/releases/R13B02/start_sasl.boot .<br />
</code></p>
<p>I configured it with &#8220;./configure &#8211;prefix=/usr &#8211;disable-x &#8211;enable-threads &#8211;enable-kernel-poll &#8211;disable-hipe&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://somic.org/2009/10/21/building-erlang-r13b02-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Full Data vs Incremental Data in Messaging</title>
		<link>http://somic.org/2009/06/25/full-data-vs-incremental-data-in-messaging/</link>
		<comments>http://somic.org/2009/06/25/full-data-vs-incremental-data-in-messaging/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 18:25:54 +0000</pubDate>
		<dc:creator>Dmitriy</dc:creator>
				<category><![CDATA[rabbitmq]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[messaging]]></category>

		<guid isPermaLink="false">http://somic.org/?p=642</guid>
		<description><![CDATA[My recent experiments with messaging for a distributed application led to a realization that I would like to share with you in this post. It&#8217;s not an earth shaking discovery but you may still find it interesting.
Do you remember an old Unix command to create tape backups called dump? Remember its concept of levels? To [...]]]></description>
			<content:encoded><![CDATA[<p>My recent experiments with messaging for a distributed application led to a realization that I would like to share with you in this post. It&#8217;s not an earth shaking discovery but you may still find it interesting.</p>
<p>Do you remember an old Unix command to create tape backups called <a href="http://linux.die.net/man/8/dump"><em>dump</em></a>? Remember its concept of levels? To refresh your memory, in a nutshell level 0 (full backup) includes all files on the filesystem, and any other level corresponds to incremental backup where only files modified since last backup are included.</p>
<p>It turns out somewhat similar concept applies to messaging, specifically to the contents of messages themselves.</p>
<p>A message in general is some piece of information that one system passes to another. On one hand, publisher may make an observation, extract information from it, package entire current state into a blob, and send it out as a message. The same sequence of operations is performed at regular intervals. Examples of this model include sending a message about processes currently running on the system, clients currently connected to a server, current usage of RAM, etc. This model roughly corresponds to dump&#8217;s level 0 &#8211; consumer needs just a single message to obtain all information that publisher sent, there is no need for consumer to accumulate and merge a series of messages to get the full picture.</p>
<p>On the other hand, a publisher can send a message that contains information about a single event. For example, a new client connected, a new job got submitted to the backend, hard disk failed. This mode is more like incremental backup &#8211; a message contains only a delta, its payload doesn&#8217;t carry entire state.</p>
<p>Each of these models has its good and bad sides. In full data model, a single message is sufficient to transfer all knowledge about current state from producer to consumer, and consumer can start reading messages at any point in the queue &#8211; by design it will catch up once it receives and processes at least one message. The downsides of this model are waste of bandwidth and processing power (if there are no changes, same contents will be transferred over and over again) and the fact that delta must be calculated by consumer (for example, having received 2 &#8220;ps auxww&#8221; outputs, consumer would have to diff them and parse the result).</p>
<p>Incremental data model clearly provides an easy delta and is less wasteful on resources, but requires consumer to merge multiple messages to get entire picture and as a result is sensitive to a point from which a consumer starts reading the queue.</p>
<p>A potential solution is to do what dump does &#8211; send full data once in a while, followed by deltas. This way consumer will catch up eventually &#8211; once it gets full data message (which will come sooner or later). Another caveat is that not always does a consumer need a full picture &#8211; in a classic scalability scenario of supervisor-workers model, workers rarely need more than contents of their current job contained in an incremental message.</p>
<p>But it&#8217;s not the end of it. While working on a problem, I realized that usually I as a developer don&#8217;t even get to choose which model to use &#8211; it&#8217;s dictated to me by the nature of information I am trying to pass from one system to another. Some data can be easily obtained as full and very difficult to obtain as incremental, some vice versa. For example, a list of current processes on Linux is trivial to obtain as full (ps auxww) and quite difficult to obtain as incremental (I would need a notification about when each process starts and dies). Or in case of incoming jobs &#8211; it&#8217;s easy to obtain delta (one job) but it&#8217;s quite difficult to know current status of all jobs.</p>
<p>My conclusion here is that there are 2 main factors to think about:</p>
<ol>
<li>can my publisher get data in full or incremental form?</li>
<li>does my consumer need data in full or incremental form?</li>
</ol>
<p>If the answers to above questions are the same, you are good to go. But if they are different, you need to understand potential issues as discussed above and analyze further. I hope to be able to provide more practical thoughts on this in the future &#8211; stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://somic.org/2009/06/25/full-data-vs-incremental-data-in-messaging/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Graphite RabbitMQ Integration</title>
		<link>http://somic.org/2009/05/21/graphite-rabbitmq-integration/</link>
		<comments>http://somic.org/2009/05/21/graphite-rabbitmq-integration/#comments</comments>
		<pubDate>Thu, 21 May 2009 14:31:49 +0000</pubDate>
		<dc:creator>Dmitriy</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[rabbitmq]]></category>
		<category><![CDATA[charts]]></category>
		<category><![CDATA[data series]]></category>
		<category><![CDATA[graphite]]></category>
		<category><![CDATA[visualizatioin]]></category>
		<category><![CDATA[webops]]></category>

		<guid isPermaLink="false">http://somic.org/?p=571</guid>
		<description><![CDATA[I started a new project on github &#8211; http://github.com/somic/graphite-rabbitmq. It currently includes a couple of tools written in Python which facilitate sending data to Graphite via RabbitMQ instead of connecting directly to the service using TCP.
Graphite is a flexible and powerful tool to build charts. It&#8217;s also a data series analytics framework. It was developed [...]]]></description>
			<content:encoded><![CDATA[<p>I started a new project on github &#8211; <a href="http://github.com/somic/graphite-rabbitmq">http://github.com/somic/graphite-rabbitmq</a>. It currently includes a couple of tools written in Python which facilitate sending data to Graphite via <a href="/category/rabbitmq">RabbitMQ</a> instead of connecting directly to the service using TCP.</p>
<div class="wp-caption alignnone" style="width: 402px"><img title="Graphite CLI Screenshot" src="http://graphite.wdfiles.com/local--files/screen-shots/graphite_cli_800.png" alt="Graphite CLI Screenshot" width="392" height="221" /><p class="wp-caption-text">Graphite CLI Screenshot</p></div>
<p>Graphite is a flexible and powerful tool to build charts. It&#8217;s also a data series analytics framework. It was developed inside Orbitz by my former colleague, originally for use within a single group (of which I was a part). However, its power did not remain a secret for too long &#8211; it quickly spread to entire organization and became an irreplaceable tool for both development and engineering/operations. Graphite was then open-sourced under Apache license. It currently lives at <a href="http://graphite.wikidot.com/">http://graphite.wikidot.com/</a></p>
<p>The key to Graphite&#8217;s power, in addition to dynamic web UI, an improved RRD implementation called &#8220;whisper&#8221; (read this <a href="http://graphite.wikidot.com/faq#toc8">FAQ</a> &#8211; highly recommend!) web-based command line with auto-completion which allows you to overlay any metrics on a single chart, IMHO is the fact that you are in control what kind of data to send to it, how often, and how to set up hierarchies of your metrics &#8211; by environment, by machine type, by datacenter, etc. Graphite doesn&#8217;t do its own polling that won&#8217;t scale to hundreds or thousands of metrics. Nor does it enforce anything but the fact that your metrics are dot-separated hierarchies (as in routing keys of AMQP topic exchanges &#8211; my.metric.name) and that their values are numeric (int or float).</p>
<p>If you are still reading this but still are not convinced that it&#8217;s the way to go, I&#8217;ve got one last argument. If you already use RabbitMQ to publish and consume data, wouldn&#8217;t it be nice to get a powerful charts without touching your application AND without installing agents on your publishers or consumers? Recall the <a href="/2008/11/11/using-rabbitmq-beyond-queueing/">duplication pattern</a> of RabbitMQ &#8211; you can fork the incoming stream of messages into another queue (without impacting your original consumers and the queues to which they attach) and set up Graphite+RabbitMQ off of this new queue.</p>
<p>If you are planning to run multiple carbon instances, remember that heavy lifting (writing to disk) is actually performed by another process called carbon-persister.py (it&#8217;s started by carbon-agent, with communications over a pipe) &#8211; try to avoid multiple persisters writing data within the same hierarchy to avoid slow down and possible data corruption. RabbitMQ can help you sort out what messages go where, thus minimizing this risk.</p>
<p>I am very excited about future opportunities that a Graphite-RabbitMQ combination can deliver, and I hope someone finds my scripts useful. Both tools bring a lot of awesomeness to the table, and nicely complement each other forming a great charts and data series analytics solution you have been searching for. Check it out!</p>
]]></content:encoded>
			<wfw:commentRss>http://somic.org/2009/05/21/graphite-rabbitmq-integration/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Adjustable Per-URI Backend Capacity in Rabbitbal</title>
		<link>http://somic.org/2009/03/11/adjustable-per-uri-backend-capacity-in-rabbitbal/</link>
		<comments>http://somic.org/2009/03/11/adjustable-per-uri-backend-capacity-in-rabbitbal/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 17:45:04 +0000</pubDate>
		<dc:creator>Dmitriy</dc:creator>
				<category><![CDATA[rabbitmq]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[rabbitbal]]></category>

		<guid isPermaLink="false">http://somic.org/?p=296</guid>
		<description><![CDATA[I recently pushed a Rabbitbal update to Github &#8211; http://github.com/somic/rabbitbal.
The biggest enhancement (IMHO) is ability to increase or decrease the number of backend consumers based on any HTTP request headers. In &#8220;table&#8221; routing mode (see rabbitbal.yml), you can now specify array of tests against which incoming request headers will be matched. This will cause your [...]]]></description>
			<content:encoded><![CDATA[<p>I recently pushed a Rabbitbal update to Github &#8211; <a href="http://github.com/somic/rabbitbal">http://github.com/somic/rabbitbal</a>.</p>
<p>The biggest enhancement (IMHO) is ability to increase or decrease the number of backend consumers based on any HTTP request headers. In &#8220;table&#8221; routing mode (see rabbitbal.yml), you can now specify array of tests against which incoming request headers will be matched. This will cause your request to be published with a matching key (note :key). Your backend consumers use the same YAML file and can bind to all or only some queues, thus giving you flexibility in adjusting the capacity. Old functionality is available by using &#8220;topic&#8221; routing mode.</p>
<p>Note that I still use topic-based exchange, because I wanted to support a use case where you want to aggregate all incoming requests into separate queues (routing key would be something like &#8220;request.#&#8221;) for bot detection, access log aggregation, etc. In other words, each request ultimately must end up in a single queue where it will be picked up by backend servers, while at the same time it can also be duplicated into other queues for other purposes.</p>
]]></content:encoded>
			<wfw:commentRss>http://somic.org/2009/03/11/adjustable-per-uri-backend-capacity-in-rabbitbal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On rabbitmqctl and badrpc,nodedown</title>
		<link>http://somic.org/2009/02/19/on-rabbitmqctl-and-badrpcnodedown/</link>
		<comments>http://somic.org/2009/02/19/on-rabbitmqctl-and-badrpcnodedown/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 16:20:42 +0000</pubDate>
		<dc:creator>Dmitriy</dc:creator>
				<category><![CDATA[erlang]]></category>
		<category><![CDATA[rabbitmq]]></category>
		<category><![CDATA[badrpc]]></category>
		<category><![CDATA[net_adm]]></category>
		<category><![CDATA[nodedown]]></category>
		<category><![CDATA[rabbitmqctl]]></category>

		<guid isPermaLink="false">http://somic.org/?p=390</guid>
		<description><![CDATA[In the true spirit of open source community that has formed around RabbitMQ in the past several years and continues growing every week, on the mailing list we have recently tackled an issue when one runs &#8220;rabbitmqctl status&#8221; and gets &#8220;badrpc,nodedown&#8221; response, while broker is running as evidenced by ps output. Check out a thread [...]]]></description>
			<content:encoded><![CDATA[<p>In the true spirit of open source community that has formed around <a href="http://www.rabbitmq.com">RabbitMQ</a> in the past several years and continues growing every week, on the mailing list we have recently tackled an issue when one runs &#8220;rabbitmqctl status&#8221; and gets &#8220;badrpc,nodedown&#8221; response, while broker is running as evidenced by <em>ps</em> output. Check out a thread on &#8220;broker runs; cant&#8217; get status&#8221; <a href="http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2009-February/">here</a>. The issue is centered around erlang&#8217;s security and communications mechanism in distributed mode. Here is a tentative step-by-step that can help you resolve the issue.</p>
<p><strong>Are you running broker as user rabbitmq and rabbitmqctl as root or rabbitmq?</strong> If not, please stop and fix this. This is not a requirement per se, but this represents canonical installation of rabbitmq broker. You can certainly hack your scripts to work around this requirement, but you are on your own if you do.</p>
<p><strong>Double check that broker is in fact running.</strong> Use <em>ps</em>, <em>netstat -lptn</em> (look for port 5672 unless you overrode it in <em>/etc/default/rabbitmq</em>). Telnet to localhost on port 5672, type <em>AMQP</em> and press ENTER several times. You should get response that at least will show <em>AMQ</em>. Check logs at /var/log/rabbitmq to verify that broker saw your connection attempt.</p>
<p><strong>Next step is to start &#8220;erl -sname foo -cookie coo&#8221; in shell and run this command: &#8220;net_adm:names().&#8221;</strong></p>
<p>If this command returns <em>ok</em> followed by a list of nodes within 1 or 2 seconds, check if rabbit is there. If it is, it&#8217;s very likely that you have users mixed up above. Please double check. If rabbit node is not listed, double check that rabbit broker is still running.</p>
<p>If this command returns <em>{error,address}</em>, there is a problem with your instance of EPMD, erlang naming daemon (<a href="http://erlang.org/doc/man/net_adm.html">man net_adm</a>). First, check if it&#8217;s running (it most likely *is* running). Then, in erlang, run &#8220;<em>net_adm:localhost().</em>&#8221; Exit erlang, and try to connect to exactly the name you got from <em>net_adm:localhost()</em> on port 4369 (epmd). This shouldn&#8217;t work and should timeout. If it doesn&#8217;t time out, you shouldn&#8217;t have gotten <em>{error,address}</em>.</p>
<p>The problem most likely will be that name as returned by <em>net_adm:localhost()</em> is associated with some IP in <em>/etc/hosts</em> or in DNS which is either not accessible from this host, or firewalled off. An entry in <em>/etc/hosts</em> that associates this name with 127.0.0.1 or one of other IPs on this server should fix the problem.</p>
<p>Alternatively, <em>net_adm:names()</em> may time out with <em>{error, timeout}</em>. <a href="/2008/04/22/snoopy-fubars-erlang/">We have seen it caused by snoopy in the past</a>. Remove snoopy or do not install it system wide in /etc/ld.so.preload, and you should be fine.</p>
<p>If these steps did not help, please leave a comment below or join <a href="http://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss">rabbitmq-discuss</a> and ask your question there, and we&#8217;ll help!</p>
<p><strong>UPDATE 2009-04-17</strong>: Your host&#8217;s name as shown by net_adm:localhost() does not technically <em>need</em> to be defined in /etc/hosts. But if it&#8217;s not there, it should not be defined anywhere &#8211; when you do &#8220;ping name&#8221;, you should get &#8220;ping: unknown host name&#8221;. I have seen at least one case when it worked this way. This is somewhat unverified though.</p>
]]></content:encoded>
			<wfw:commentRss>http://somic.org/2009/02/19/on-rabbitmqctl-and-badrpcnodedown/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>RabbitMQ and Rails</title>
		<link>http://somic.org/2009/01/29/rabbitmq-and-rails/</link>
		<comments>http://somic.org/2009/01/29/rabbitmq-and-rails/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 23:43:37 +0000</pubDate>
		<dc:creator>Dmitriy</dc:creator>
				<category><![CDATA[rabbitmq]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://somic.org/?p=367</guid>
		<description><![CDATA[A quick note. This blog is getting a lot of google referrals for people looking for &#8220;rabbitmq rails&#8221;. I just wanted to say that I do not have good up-to-date material on the subject. Instead, check out this thread on ruby-amqp mailing list and consider tmm1-amqp gem for your project.
]]></description>
			<content:encoded><![CDATA[<p>A quick note. This blog is getting a lot of google referrals for people looking for &#8220;rabbitmq rails&#8221;. I just wanted to say that I do not have good up-to-date material on the subject. Instead, check out this <a href="http://groups.google.com/group/ruby-amqp/browse_thread/thread/3b39343aac6a7db5">thread</a> on ruby-amqp mailing list and consider <a href="http://github.com/tmm1/amqp">tmm1-amqp</a> gem for your project.</p>
]]></content:encoded>
			<wfw:commentRss>http://somic.org/2009/01/29/rabbitmq-and-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing Rabbitbal</title>
		<link>http://somic.org/2008/12/18/introducing-rabbitbal/</link>
		<comments>http://somic.org/2008/12/18/introducing-rabbitbal/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 14:47:39 +0000</pubDate>
		<dc:creator>Dmitriy</dc:creator>
				<category><![CDATA[rabbitmq]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[amqp]]></category>
		<category><![CDATA[reverse proxy]]></category>

		<guid isPermaLink="false">http://somic.org/?p=253</guid>
		<description><![CDATA[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&#8217;s now available on github at [...]]]></description>
			<content:encoded><![CDATA[<p>Inspired by <a href="http://github.com/ezmobius/nanite/tree/master">Nanite</a>, a very interesting project by <a href="http://brainspl.at/articles/2008/10/11/merbcamp-keynote-and-introducing-nanite">Ezra Zygmuntowicz</a> of EngineYard that uses <a href="http://www.rabbitmq.com">RabbitMQ</a> and eventmachine-based <a href="http://github.com/tmm1/amqp">ruby amqp library</a> 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&#8217;s now available on github at <a href="http://github.com/somic/rabbitbal">http://github.com/somic/rabbitbal</a>. Rabbitbal code is based on Nanite.</p>
<p>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.</p>
<ol>
<li>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.</li>
<li>RabbitMQ broker implements intelligent failover out of the box &#8211; if a web server disconnects before ack&#8217;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.</li>
<li>Enhanced security of actual web servers &#8211; servers behind Rabbitbal do not need inbound connectivity, they only need to be able to establish an outgoing connection to RabbitMQ broker(s).</li>
<li>Rabbitbal does not need to know IPs or have direct connectivity into its web servers (use case: Amazon EC2 without Elastic IPs)</li>
<li>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)</li>
<li>You could relatively easily have one request go to more than 1 web server</li>
<li>Add capacity as often and as much as you like &#8211; rabbitbal won&#8217;t even know</li>
<li>By slightly readjusting mapping between queues and URIs, you could add or remove capacity per URI if needed</li>
<li>TCP overhead savings compared with HTTP proxies (AMQP uses persistent TCP connections)</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://somic.org/2008/12/18/introducing-rabbitbal/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using RabbitMQ Beyond Queueing</title>
		<link>http://somic.org/2008/11/11/using-rabbitmq-beyond-queueing/</link>
		<comments>http://somic.org/2008/11/11/using-rabbitmq-beyond-queueing/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 15:16:05 +0000</pubDate>
		<dc:creator>Dmitriy</dc:creator>
				<category><![CDATA[rabbitmq]]></category>

		<guid isPermaLink="false">http://somic.org/?p=152</guid>
		<description><![CDATA[UPDATED 2008-11-12: Adjusted Failover section below (additions in italic) based on a thread on rabbit-discuss.
I am a big fan of RabbitMQ, an implementation of Advanced Message Queueing Protocol. In this post I am going to provide an overview how RabbitMQ can be used beyond simple queueing and pubsub. For more background on this topic, please [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATED 2008-11-12</strong>: Adjusted Failover section below (additions in italic) based on a <a href="http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2008-November/002354.html">thread</a> on rabbit-discuss.</p>
<p>I am a big fan of <a href="http://www.rabbitmq.com">RabbitMQ</a>, an implementation of <a href="http://amqp.org">Advanced Message Queueing Protocol</a>. In this post I am going to provide an overview how RabbitMQ can be used beyond simple queueing and pubsub. For more background on this topic, please see a <a href="http://www.rabbitmq.com/faq.html#scenarios">list of messaging scenarios</a> that RabbitMQ supports.</p>
<h3>Queueing</h3>
<p>Broker can take a message from producer and keep it until a consumer shows up. To survive broker restarts, queues in this case should be durable, with auto-delete set to false, and messages should be published with delivery mode of 2 (which means persistent). This pattern can also be helpful if consumer is temporarily unable to keep up with incoming message flow -  queueing allows producer and consumer to keep going at their own pace, and will make sure all messages are consumed eventually.</p>
<h3><a href="http://en.wikipedia.org/wiki/Multiplexing">Multiplex</a></h3>
<p>This is when multiple producers publish messages to be routed to a single consumer. You can either have all your producers publish to the same fanout exchange, or to the same direct exchange with the same routing key, or to a topic exchange with a routing key that matches that of consumer. The latter case allows producers to publish &#8220;flights.aa.ord&#8221; and &#8220;flights.ua.sfo&#8221;, while the consumer can be reading all of these with &#8220;flights.#&#8221; (* matches a single word, # matches zero or more words).</p>
<h3><a href="http://en.wikipedia.org/wiki/Demultiplexer">Demultiplex</a></h3>
<p>This is when a single producer publishes messages that are routed to multiple different consumers. It can be a topic exchange, producer could publish &#8220;order.book&#8221; and &#8220;order.cd&#8221;, while orders for books and CDs are handled by different systems.</p>
<h3>Instant Feedback (Queueing Bypass)</h3>
<p>Producer can instruct broker not to queue a message at all and return it to sender if a consumer is not currently available to read it (this is achieved by setting immediate flag to true in basic.publish method). Can be helpful in scenarios where message content is time sensitive &#8211; it needs to be processed now or an error must be returned.</p>
<h3>Duplicating</h3>
<p>In AMQP, a message is delivered to all queues bound to a given exchange, if a queue meets routing criteria (for different types of exchanges, these criteria are different). For example, a message published with &#8220;prod.server01.disk.full&#8221; key can be simultaneously routed to &#8220;prod.#&#8221; queue (for production logger to keep track of all events in production environment) and &#8220;#.disk.full&#8221; queue (for an archiver process that removes old logs). Very powerful feature, and it works with direct and fanout exchanges as well.</p>
<h3>Load balancing</h3>
<p>If multiple consumers read from the same queue, RabbitMQ broker will automatically load balance messages between all available consumers. Each message will be sent to one consumer at a time.</p>
<h3>Failover</h3>
<p>In no_ack=false mode, a consumer must <em>eventually</em> explicitly acknowledge receipt of each message, <em>individually or as a group</em> <em>(this does not mean that a message must be ack&#8217;ed before next one can be received)</em>. If a consumer disconnects without acknowledging, <em>unack&#8217;ed</em> messages are automatically re-queued for another consumer. This helps achieve consumer failover in response to crashes or <a href="/2008/10/10/crash-vs-connectivity-loss-in-distributed-applications/">loss of network connectivity</a>.</p>
<h3>Relaying</h3>
<p>If producers and consumers do not have direct line of sight network-wise (for example, they are behind NAT or are located on private subnets), RabbitMQ can provide the connectivity by serving as a message relayer. Both producers and consumers must be able to establish client connections to broker (AMQP official port is TCP 5672) and then they can exchange messages.</p>
<p>Some of these patterns can be mixed and matched, which further expands a set of problems where RabbitMQ can help you achieve a distributed messaging nirvana.</p>
]]></content:encoded>
			<wfw:commentRss>http://somic.org/2008/11/11/using-rabbitmq-beyond-queueing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides for my AMQP/RabbitMQ Talk</title>
		<link>http://somic.org/2008/07/31/slides-for-my-amqprabbitmq-talk/</link>
		<comments>http://somic.org/2008/07/31/slides-for-my-amqprabbitmq-talk/#comments</comments>
		<pubDate>Thu, 31 Jul 2008 22:28:28 +0000</pubDate>
		<dc:creator>Dmitriy</dc:creator>
				<category><![CDATA[rabbitmq]]></category>
		<category><![CDATA[amqp]]></category>
		<category><![CDATA[cohesiveft]]></category>
		<category><![CDATA[elastic server]]></category>
		<category><![CDATA[slides]]></category>

		<guid isPermaLink="false">http://somic-org.homelinux.org/blog/2008/07/31/slides-for-my-amqprabbitmq-talk/</guid>
		<description><![CDATA[I recently gave a talk titled Introduction to AMQP Messaging with RabbitMQ at a big web technology company in Chicago. You can now see the slides here on Slideshare, or download PDF.
]]></description>
			<content:encoded><![CDATA[<p>I recently gave a talk titled <em><strong>Introduction to <a href="http://amqp.org">AMQP</a> Messaging with <a href="http://www.rabbitmq.com">RabbitMQ</a></strong></em> at a big web technology company in Chicago. You can now see the slides <a href="http://www.slideshare.net/somic/introduction-to-amqp-messaging-with-rabbitmq">here on Slideshare</a>, or download <a href="http://www.slideshare.net/somic/introduction-to-amqp-messaging-with-rabbitmq/download">PDF</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://somic.org/2008/07/31/slides-for-my-amqprabbitmq-talk/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
