<?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>RabbitMQ</title>
	<atom:link href="http://www.rabbitmq.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rabbitmq.com/blog</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Wed, 01 May 2013 16:09:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>RabbitMQ 3.1&#8230; in images</title>
		<link>http://www.rabbitmq.com/blog/2013/05/01/rabbitmq-3-1-0-in-images/</link>
		<comments>http://www.rabbitmq.com/blog/2013/05/01/rabbitmq-3-1-0-in-images/#comments</comments>
		<pubDate>Wed, 01 May 2013 16:06:30 +0000</pubDate>
		<dc:creator>Simon MacMullen</dc:creator>
				<category><![CDATA[New Features]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[whimsical]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=421</guid>
		<description><![CDATA[Charts Syncing Limited-length queues Filters Less scrolling AMQP 1.0 support autoheal (OK that last one was a bit of a stretch...)]]></description>
			<content:encoded><![CDATA[<h3>Charts</h3>

<p><a href="http://www.rabbitmq.com/wp-uploads/2013/05/chart.png"><img src="http://www.rabbitmq.com/wp-uploads/2013/05/chart.png" alt="" title="chart" width="640" height="150" class="alignnone size-full wp-image-441" /></a>
<span id="more-421"></span></p>

<h3>Syncing</h3>

<p><a href="http://www.rabbitmq.com/wp-uploads/2013/05/syncing.png"><img src="http://www.rabbitmq.com/wp-uploads/2013/05/syncing.png" alt="" title="syncing" width="796" height="124" class="alignnone size-full wp-image-432" /></a></p>

<h3>Limited-length queues</h3>

<p><a href="http://www.rabbitmq.com/wp-uploads/2013/05/limited.png"><img src="http://www.rabbitmq.com/wp-uploads/2013/05/limited.png" alt="" title="limited" width="700" height="112" class="alignnone size-full wp-image-431" /></a></p>

<h3>Filters</h3>

<p><a href="http://www.rabbitmq.com/wp-uploads/2013/05/filter.png"><img class="alignnone size-full wp-image-426" title="filter" src="http://www.rabbitmq.com/wp-uploads/2013/05/filter.png" alt="" width="600" height="300" /></a></p>

<h3>Less scrolling</h3>

<p><a href="http://www.rabbitmq.com/wp-uploads/2013/05/banner.png"><img class="alignnone size-full wp-image-424" title="banner" src="http://www.rabbitmq.com/wp-uploads/2013/05/banner.png" alt="" width="562" height="164" /></a></p>

<h3>AMQP 1.0 support</h3>

<p><a href="http://www.rabbitmq.com/wp-uploads/2013/05/amqp1.0.png"><img class="alignnone size-full wp-image-422" title="amqp1.0" src="http://www.rabbitmq.com/wp-uploads/2013/05/amqp1.0.png" alt="" width="426" height="200" /></a></p>

<h3>autoheal</h3>

<p><a href="http://www.rabbitmq.com/wp-uploads/2013/05/autoheal.png"><img class="alignnone size-full wp-image-423" title="autoheal" src="http://www.rabbitmq.com/wp-uploads/2013/05/autoheal.png" alt="" width="602" height="154" /></a></p>

<p>(OK that last one was a bit of a stretch...)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2013/05/01/rabbitmq-3-1-0-in-images/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What&#8217;s new in RabbitMQ 3.0?</title>
		<link>http://www.rabbitmq.com/blog/2012/11/20/whats-new-in-rabbitmq-3-0/</link>
		<comments>http://www.rabbitmq.com/blog/2012/11/20/whats-new-in-rabbitmq-3-0/#comments</comments>
		<pubDate>Tue, 20 Nov 2012 16:31:12 +0000</pubDate>
		<dc:creator>Simon MacMullen</dc:creator>
				<category><![CDATA[New Features]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=390</guid>
		<description><![CDATA[So we've talked about how RabbitMQ 3.0 can break things, but that's not very positive. Let's have a look at some of the new features! Just some of them - quite a lot changed in 3.0, and we don't have all day... Policy-based mirroring You can now define queue mirroring in a much simpler and [...]]]></description>
			<content:encoded><![CDATA[<p>So we've talked about how <a href="http://www.rabbitmq.com/blog/2012/11/19/breaking-things-with-rabbitmq-3-0/">RabbitMQ 3.0 can break things</a>, but that's not very positive. Let's have a look at some of the new features! Just some of them - <a href="http://www.rabbitmq.com/release-notes/README-3.0.0.txt">quite a lot changed in 3.0</a>, and we don't have all day...
<span id="more-390"></span></p>

<h3>Policy-based mirroring</h3>

<p><a href="http://www.rabbitmq.com/wp-uploads/2012/11/policy-ha.png"><img src="http://www.rabbitmq.com/wp-uploads/2012/11/policy-ha-300x81.png" alt="" title="Policy based HA" width="300" height="81" class="alignright size-medium wp-image-399" /></a>You can now <a href="http://www.rabbitmq.com/ha.html">define queue mirroring</a> in a much simpler and more flexible way. Your applications no longer need to know about it, and can work the same way in development and production. You can take an existing unmirrored queue and make it become mirrored with no downtime (and vice versa of course). Furthermore you can now mirror queues on to a set number of nodes in a cluster.</p>

<h3>Faster mirroring</h3>

<p>Mirrored queues have also become much faster - while the improvement in performance depends on a variety of factors, it is not unknown to see mirrored queues running an order of magnitude faster, or even more.</p>

<h3>Dynamic federation</h3>

<p><a href="http://www.rabbitmq.com/wp-uploads/2012/11/federation.png"><img src="http://www.rabbitmq.com/wp-uploads/2012/11/federation-300x39.png" alt="" title="Dynamic Federation" width="300" height="39" class="alignright size-medium wp-image-395" /></a>Federation has also become <a href="http://www.rabbitmq.com/federation.html">more flexible, transparent to applications, and dynamic</a>. You can federate or unfederate exchanges at any time; and add, remove and reconfigure upstreams without changing anything.</p>

<h3>New clustering commands</h3>

<p>Clustering is now easier to <a href="http://www.rabbitmq.com/clustering.html">set up</a>, and more checks for cluster consistency are performed at each step in the process. It's also now possible to remove a dead node from a cluster without its cooperation.</p>

<h3>Partition detection</h3>

<p><a href="http://www.rabbitmq.com/wp-uploads/2012/11/partition.png"><img src="http://www.rabbitmq.com/wp-uploads/2012/11/partition-300x98.png" alt="" title="Partition detection" width="300" height="98" class="alignright size-medium wp-image-398" /></a><a href="http://www.rabbitmq.com/partitions.html">Network partitions</a> in clusters are a bad thing - so RabbitMQ will now display a large warning in the management plugin when one has occurred (this is also available in <code>rabbitmqctl cluster_status</code>).</p>

<h3>Per-message TTL</h3>

<p>As well as being able to specify a TTL for messages on a per-queue basis, individual messages can also <a href="http://www.rabbitmq.com/ttl.html#per-message-ttl">have a TTL set</a> when they are published.</p>

<h3>Enabling heartbeats by default</h3>

<p>Since so many people have experienced problems with long-running idle connections being interrupted by network infrastructure, the server now proposes AMQP heartbeats every 10 minutes by default during connection negotiation. This value can be <a href="http://www.rabbitmq.com/configure.html#configuration-file">configured here</a>.</p>

<h3>Memory use statistics</h3>

<p><a href="http://www.rabbitmq.com/wp-uploads/2012/11/memory.png"><img src="http://www.rabbitmq.com/wp-uploads/2012/11/memory-300x88.png" alt="" title="Memory statistics" width="300" height="88" class="alignright size-medium wp-image-397" /></a>It's now possible to get a simple overview of <a href="http://www.rabbitmq.com/memory-use.html">where the memory used by your broker is going</a>.</p>

<h3>Background GC</h3>

<p>Certain long-running processes have ended up consuming a lot of memory while waiting for garbage collection. RabbitMQ now forcibly GCs idle processes in the background, cutting down on excess memory use.</p>

<h3>Reverse DNS lookups</h3>

<p><a href="http://www.rabbitmq.com/wp-uploads/2012/11/rdns.png"><img src="http://www.rabbitmq.com/wp-uploads/2012/11/rdns-300x113.png" alt="" title="Reverse DNS" width="300" height="113" class="alignright size-medium wp-image-400" /></a>Just a small thing - but you can now have RabbitMQ perform reverse DNS lookups on connecting clients to give clearer names in management and rabbitmqctl. Just set <code>{reverse_dns_lookups, true}</code> in your <a href="http://www.rabbitmq.com/configure.html#configuration-file">rabbitmq.config</a>.</p>

<h3>Web-STOMP and MQTT</h3>

<p>We've added plugins to support <a href="http://www.rabbitmq.com/blog/2012/05/14/introducing-rabbitmq-web-stomp/">STOMP-over-websockets</a> (with SockJS support for non-websocket browsers) and <a href="https://www.ibm.com/developerworks/webservices/library/ws-mqtt/">MQTT 3.1</a>. We've also added support for <a href="http://stomp.github.com/stomp-specification-1.2.html">STOMP 1.2</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2012/11/20/whats-new-in-rabbitmq-3-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Breaking things with RabbitMQ 3.0</title>
		<link>http://www.rabbitmq.com/blog/2012/11/19/breaking-things-with-rabbitmq-3-0/</link>
		<comments>http://www.rabbitmq.com/blog/2012/11/19/breaking-things-with-rabbitmq-3-0/#comments</comments>
		<pubDate>Mon, 19 Nov 2012 12:15:28 +0000</pubDate>
		<dc:creator>Simon MacMullen</dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[New Features]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=365</guid>
		<description><![CDATA[RabbitMQ includes a bunch of cool new features. But in order to implement some of them we needed to change some things. So in this blog post I'm going to list some of those things in case you need to do anything about them. Mirror queue policies What changed? In RabbitMQ 3.0, queue mirroring is [...]]]></description>
			<content:encoded><![CDATA[<p>RabbitMQ includes a bunch of cool new features. But in order to implement some of them we needed to change some things. So in this blog post I'm going to list some of those things in case you need to do anything about them.
<span id="more-365"></span></p>

<h3>Mirror queue policies</h3>

<p><strong>What changed?</strong> In RabbitMQ 3.0, queue mirroring is no longer controlled by the <code>x-ha-policy</code> argument when declaring a queue. Your applications can continue to declare this argument, but it won't cause queues to be mirrored. Instead you can declare one or more <a href="http://www.rabbitmq.com/parameters.html">policies</a> which control which queues are mirrored, and how.</p>

<p><strong>Why did it change?</strong> As anyone who's used mirrored queues will tell you, requiring applications to know which queues are mirrored is a pain. The new approach puts configuration in the broker, where it belongs, and also supports changing mirroring policy at any time.</p>

<p><strong>What should I do?</strong> You need to make sure your queues are still mirrored. For the full documentation <a href="http://www.rabbitmq.com./ha.html">see here</a>, but if you just want to make sure that all queues (except those with auto-generated names) are mirrored across all nodes, run:</p>

<p><code>rabbitmqctl set_policy HA '^(?!amq\.).*' '{"ha-mode": "all"}'</code></p>

<h3>New federation</h3>

<p><strong>What changed?</strong> Federation is configured quite differently in RabbitMQ 3.0. The <code>x-federation</code> exchange type no longer exists; instead normal exchanges are made federated by policy in the same way that HA queues are. Furthermore, upstreams are defined dynamically as well.</p>

<p><strong>Why did it change?</strong> Again, your applications should not need to know about federation. Federation configuration in <code>rabbitmq.config</code> was complicated and confused many people. And needing to restart the broker to add a new upstream was not fun.</p>

<p><strong>But I have a working federation setup! You broke it.</strong> Migrating to the <a href="http://www.rabbitmq.com/federation.html">new way of doing federation</a> will take a bit of work. In the mean time you can use the <code>rabbitmq_old_federation</code> plugin. This is a backport of the 2.8.7 federation plugin for RabbitMQ 3.0. To use it:</p>

<p><code>rabbitmq-plugins disable rabbitmq_federation</code></p>

<p><code>rabbitmq-plugins enable rabbitmq_old_federation</code></p>

<p>and then edit your <code>rabbitmq.config</code> file so that the <code>rabbitmq_federation</code> section is renamed to <code>rabbitmq_old_federation</code>.</p>

<h3>New clustering</h3>

<p><strong>What changed?</strong> The clustering-setup commands in rabbitmqctl have changed.</p>

<p><strong>Why did it change?</strong> The old ones were not very user friendly.</p>

<p><strong>What do I need to do?</strong> If you have an existing cluster, nothing. If you write scripts to create clusters, you will need to edit them. In particular, <code>rabbitmqctl cluster</code> should be replaced with <code>rabbitmqctl join_cluster</code>, but:</p>

<ul>
    <li>You don't need to invoke <code>rabbitmqctl reset</code> first</li>
    <li>You don't need to list all the nodes on the command line; if you give more than one node then they will be taken as a list of nodes to try to cluster with</li>
    <li>Whether the new node is a disc or RAM node is determined by the --disc and --ram flags. The default is to be a disc node.</li>
</ul>

<p>For more details, see <a href="http://www.rabbitmq.com/man/rabbitmqctl.1.man.html#join_cluster">the documentation</a>.</p>

<h3>Removal of "immediate" flag</h3>

<p><strong>What changed?</strong> We removed support for the rarely-used "immediate" flag on AMQP's basic.publish.</p>

<p><strong>Why on earth did you do that?</strong> Support for "immediate" made many parts of the codebase more complex, particularly around mirrored queues. It also stood in the way of our being able to deliver substantial performance improvements in mirrored queues.</p>

<p><strong>What do I need to do?</strong> 
If you just want to be able to publish messages that will be dropped if they are not consumed immediately, you can publish to a queue <a href="http://www.rabbitmq.com/ttl.html">with a TTL of 0</a>.</p>

<p>If you also need your publisher to be able to determine that this has happened, you can also use the <a href="http://www.rabbitmq.com/dlx.html">DLX</a> feature to route such messages to another queue, from which the publisher can consume them.</p>

<h3>frame_max</h3>

<p><strong>What changed?</strong> The RabbitMQ server now disconnects clients which send frames larger than the negotiated <code>frame_max</code> setting for the connection.</p>

<p><strong>Why did it change?</strong> Malicious (or badly written) clients could send arbitrarily large frames and cause the server to run out of memory.</p>

<p><strong>Why do I care?</strong> Unfortunately some clients don't implement AMQP framing correctly. RabbitMQ 3.0 will allow clients to exceed <code>frame_max</code> by a fudge factor of a few bytes (to allow for off by one errors and incorrectly excluding the frame header) but if your client has broken framing you will be disconnected after trying to send a message larger than <code>frame_max</code> (which by default comes out to 128kb; see the <a href="http://www.rabbitmq.com/configure.html#config-items">documentation</a> on how to raise this).</p>

<h3>Management and JSON-RPC channel port changes</h3>

<p><strong>What changed?</strong> The management plugin now listens on port 15672, not 55672. JSON-RPC channel now listens on 15670, not 55670.</p>

<p><strong>Why did it change?</strong> The old ports were in the ephemeral port range on many operating systems, meaning that web browsers and other client applications might use these ports arbitrarily. You're not supposed to listen on these ports.</p>

<p>In particular we noticed that the management plugin web UI could, when pointed at a stopped broker on localhost, end up getting the browser to connect to itself on port 55672. This prevented the broker from starting again.</p>

<p><strong>What do I have to do?</strong> Hopefully nothing. RabbitMQ will attempt to open the old port and send HTTP redirects to the new one. But if you're using an application other than a web browser to talk to the HTTP API, it might not support HTTP redirects. If it doesn't, you'll need to point it at the new port.</p>

<p>Note that <code>rabbitmqadmin</code> prior to version 3.0 was such an application. Oops.</p>

<p>Also note that the STOMP plugin still listens on port 61313. Although this is in the ephemeral range, it's the closest thing STOMP has to a standard port, so we have to stick with it.</p>

<h3>expiration property</h3>

<p><strong>What changed?</strong> We now expect the expiration field in message properties to be parseable as an integer if it's set at all.</p>

<p><strong>Why did it change?</strong> In order to support <a href="http://www.rabbitmq.com/ttl.html#per-message-ttl">per-message TTL</a> we need a place to get the TTL of the message from, and this is the obvious place. Unfortunately the AMQP standard defines it as a string, so we try to parse it as an integer and will throw a channel exception if it is not.</p>

<p><strong>What do I have to do?</strong> Make sure that if you're using that property then you're using it because you expect RabbitMQ to expire the message, and make sure it's set to a string which can be parsed as an integer.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2012/11/19/breaking-things-with-rabbitmq-3-0/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>MQTT Adapter</title>
		<link>http://www.rabbitmq.com/blog/2012/09/12/mqtt-adapter/</link>
		<comments>http://www.rabbitmq.com/blog/2012/09/12/mqtt-adapter/#comments</comments>
		<pubDate>Wed, 12 Sep 2012 16:32:30 +0000</pubDate>
		<dc:creator>Emile Joubert</dc:creator>
				<category><![CDATA[New Features]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=328</guid>
		<description><![CDATA[I've written a plugin for RabbitMQ that adds support for the MQTT 3.1 protocol. MQ Telemetry Transport is a light-weight PUB/SUB protocol designed for resource-constrained devices and limited bandwidth situations, making it ideally suited to sensors and mobile devices. The implementation is a protocol adapter  plugin, allowing MQTT clients to connect to a RabbitMQ broker [...]]]></description>
			<content:encoded><![CDATA[<p>I've written a plugin for RabbitMQ that adds support for the <a title="MQTT" href="https://www.ibm.com/developerworks/webservices/library/ws-mqtt/">MQTT 3.1</a> protocol. MQ Telemetry Transport is a light-weight PUB/SUB protocol designed for resource-constrained devices and limited bandwidth situations, making it ideally suited to sensors and mobile devices. The implementation is a protocol adapter  plugin, allowing MQTT clients to connect to a RabbitMQ broker simultaneously with clients implementing other protocols. We encourage projects that demand the combination of a low-overhead protocol on a robust, scalable broker with high reliability and enterprise features to consider this option.
<span id="more-328"></span></p>

<h2>Supported features</h2>

<dl><dt>QoS 0 and QoS 1</dt><dd>The MQTT adapter supports QoS 0 (at most once) and QoS 1 (at least once) semantics. In MQTT QoS relates to transport assurance as well as persistence - the plugin honours both. While clients are permitted to request QoS 2 subscriptions, the adapter will only grant subscriptions up to QoS 1.</dd><dt>Last Will and Testament (LWT)</dt><dd>Clients can provide a LWT message during connection that will only be published if the client disconnects unexpectedly, e.g. due to a network failure.</dd><dt>Sticky sessions</dt><dd>Clients can make use of sticky (or non-clean) sessions to ensure they receive messages that were published whilst they were disconnected.</dd><dt>Default logins</dt><dd>Default authentication details can be optionally be configured so that the MQTT adapter authenticates to the RabbitMQ broker as a default user in case a connecting MQTT client provides no login details.</dd></dl>

<h2>Extended features</h2>

<p>While not explicitly enumerated, all core broker features are available to MQTT clients.</p>

<p>MQTT subscription wildcards are limited in that they may only appear as a suffix. AMQP topics are not limited in this way, so wildcards can appear in any position. The MQTT adapter implements the more flexible AMQP patterns, but with MQTT syntax.</p>

<p>The MQTT specification does not mention SSL or any interaction between SSL and authentication. The MQTT adapter includes SSL capability now, with the possibility of integrating  certificates with authentication on the future.</p>

<p>The MQTT concept of "bridging" can be realised with RabbitMQ's <a href="http://www.rabbitmq.com/federation.html">federation</a> by federating the exchanges that the MQTT adapter publishes to.</p>

<h2>Future features</h2>

<p>AMQP 0-9-1 does not define "exactly once" semantics for message delivery. For this reason the MQTT adapter does not support publishing messages at the QoS 2 (exactly once) level, or exchanging PUBREC, PUBREL or PUBCOMP messages with clients.</p>

<p>"Retained  messages" is an MQTT feature where the broker retains flagged messages and delivers them to future subscribing clients. E.g. in a topic for sensor readings, a retained message allows a client to receive the last reading without  needing to wait for the next reading. By default AMQP 0-9-1 exchanges do not retain any message state. Therefore the MQTT adapter makes no attempt to honour the "Retained" flag, which will be silently ignored.</p>

<p>These are areas where we are especially interested in obtaining feedback from the community. There is scope to enhance the core broker with these features not only for MQTT clients, but potentially for (extended) AMQP and other clients as well - provided there is sufficient demand.</p>

<h2>Interoperability with other MQTT implementations</h2>

<p>The MQTT adapter has been successfully tested with the MQTT clients of the following products, when restricting operation to the supported features:</p>

<ul>
    <li>Really Small Message Broker</li>
    <li>Mosquitto</li>
    <li>Paho</li>
    <li>WebSphere MQ</li>
</ul>

<h2>Interoperability with other protocols</h2>

<p>The MQTT adapter uses one configurable exchange for publishing, and subscriptions are implemented as AMQP bindings. In combination these allow interoperability with any clients that know the name of the exchange or the topics used by MQTT clients.</p>

<h2>Installation</h2>

<p>First make sure you have  <a href="http://www.rabbitmq.com/download.html">rabbitmq-server 2.8.6</a> installed. (The plugin should also be compatible with other v2.8.x releases.)</p>

<p>The MQTT adapter is currently available as a preview release. You must download and install the plugin manually until it  is included as a regular plugin in a future release. The plugin can be downloaded from the <a href="http://www.rabbitmq.com/releases/plugins/v2.8.6-mqtt-preview/rabbitmq_mqtt-2.8.6.ez">preview release downloads</a>, e.g.</p>

<pre><code> wget http://www.rabbitmq.com/releases/plugins/v2.8.6-mqtt-preview/rabbitmq_mqtt-2.8.6.ez</code></pre>

<p>The *.ez file must be copied to the <a href="http://www.rabbitmq.com/plugins.html#installing-plugins">plugins directory</a>. On my Debian-based workstation this is in <code> /usr/lib/rabbitmq/lib/rabbitmq_server-2.8.6/plugins</code>:</p>

<pre><code> sudo cp <code>rabbitmq_mqtt-2.8.6.ez</code> /usr/lib/rabbitmq/lib/rabbitmq_server-2.8.6/plugins</code></pre>

<p>Enable the plugin using <a href="http://www.rabbitmq.com/plugins.html">rabbitmq-plugins</a>:</p>

<pre><code> sudo rabbitmq-plugins enable rabbitmq_mqtt</code></pre>

<p>Restart the rabbitmq server</p>

<pre><code> sudo /etc/init.d/rabbitmq-server restart </code></pre>

<p>The broker logfile should now include a new line indicating that it is ready to accept MQTT connections:</p>

<pre>  =INFO REPORT==== 12-Sep-2012::14:21:26 ===
  started MQTT TCP Listener on [::]:1883</pre>

<p>The default configuration options should work fine  in most cases. A description of all configuration options is included in the <a href="http://hg.rabbitmq.com/rabbitmq-mqtt/file/default/README.md">readme</a>. You will need to provide further configuration if you wish to set up SSL, or define a different exchange in order to facilitate <a href="http://www.rabbitmq.com/federation.html">federation</a>.</p>

<p>You can now try to execute the <a href="http://hg.rabbitmq.com/rabbitmq-mqtt/file/default/test/src/com/rabbitmq/mqtt/test/MqttTest.java">included tests</a> (based on the Java Paho client library), or your own MQTT application.</p>

<p>See the <a href="http://www.rabbitmq.com/contact.html">contact</a> page for details on how to provide feedback.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2012/09/12/mqtt-adapter/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Jason and Alvaro&#8217;s excellent Rabbit book</title>
		<link>http://www.rabbitmq.com/blog/2012/05/29/jason-and-alvaros-excellent-rabbit-book/</link>
		<comments>http://www.rabbitmq.com/blog/2012/05/29/jason-and-alvaros-excellent-rabbit-book/#comments</comments>
		<pubDate>Tue, 29 May 2012 10:35:47 +0000</pubDate>
		<dc:creator>alexis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=316</guid>
		<description><![CDATA[Here at Rabbit HQ we've been enjoying "RabbitMQ in Action", the introduction to RabbitMQ and messaging.  Part of the Manning series, the book is written by Jason Williams and Alvaro Videla, both well known for their many contributions to the Rabbit community. Today we'd like to say thank-you to Jason and Alvaro.  Thank-you Jason and Alvaro! [...]]]></description>
			<content:encoded><![CDATA[<p>Here at Rabbit HQ we've been enjoying "<a href="http://manning.com/videla/">RabbitMQ in Action</a>", the introduction to RabbitMQ and messaging.  Part of the <a href="http://www.manning.com/">Manning series</a>, the book is written by <a href="http://blogs.digitar.com/jjww/">Jason Williams</a> and <a href="http://videlalvaro.github.com/">Alvaro Videla</a>, both well known for their many contributions to the Rabbit community.</p>

<p>Today we'd like to say thank-you to Jason and Alvaro.  Thank-you Jason and Alvaro!  You did an amazing job and infinite beers are on us.</p>

<p>But there's more...  Manning have kindly offered a promotional discount of 37% to readers of this blog.  All is revealed below, in a guest post by Jason Williams himself...</p>

<h2>RabbitMQ in Action is here</h2>

<p>Well, it's finally here. After 18 months of writing, re-writing and updating, RabbitMQ in Action is finished and in the flesh. It's hard to believe that when we started, RabbitMQ was at version 1.8.0 and <a href="http://www.rabbitmq.com/news.html#2012-04-30T13:00:12+0100">now we're at 2.8.2</a>. So much has changed in Rabbit that required rewrites of whole sections along the way, that it feels like we're really at 5 or 6.0. It's a testament to the Rabbit team members that helped us that the book kept pace with it all. So now that it's out why should you read it (besides the 37% discount code below)?</p>

<p>If you feel like you want a deeper understanding than the <a href="http://www.rabbitmq.com/getstarted.html">online tutorials</a> offer, we wrote this for you. Whether it's figuring out <a href="http://www.rabbitmq.com/clustering.html">clustering</a> and <a href="http://www.rabbitmq.com/ha.html">mirrored queues</a>, or just getting a better understanding of messaging fabrics (<a href="http://www.rabbitmq.com/tutorials/amqp-concepts.html">queues, bindings and routing exchanges</a>, <a href="http://www.rabbitmq.com/distributed.html">relays and federations</a>.), our goal was to write the book we wished had existed when we started, and that we hope will help you. From the <a href="http://www.rabbitmq.com/management.html">management console and API</a> to building real world applications and <a href="http://www.rabbitmq.com/plugins.html">plugins</a>, we've tried to cover everything you need to get a good foundation of Rabbit under your belt…and hopefully that you can use as a desk reference too.</p>

<h2>Lots of example code on Github to get you started</h2>

<p>One thing we tried to focus on was using RabbitMQ to link together different applications written in completely different languages.  That's one of the main reasons we wrote the examples in Python and PHP. However, we had two other reasons also:</p>

<p>1.) Python reads almost like pseudo-code and produces incredibly readable programs…which makes it an excellent teaching language. You can focus on what the example program's doing, without a lot of class declarations and boiler plate clouding up the works.</p>

<p>2.) There are a ton of books on messaging targeted at Java and the old-line enterprise brokers. We wanted to write something different... something that was easier to read and more accessible to people without any background in messaging. RabbitMQ in Action is very
much a book for people of all languages and backgrounds. Writing in Python and PHP helped us do that (there's appendices on using Rabbit with Java and .NET too).</p>

<p>With that last one in mind, we’ve done something a little different than other Manning books…all of our examples are in a <a href="https://github.com/rabbitinaction/sourcecode">public repo on Github</a>.</p>

<p>We did this so that if you feel like converting the examples into the language of your choice to help those like you, you can. As long as the license on your contribution is <a href="http://en.wikipedia.org/wiki/BSD_licenses">BSD</a>, we'll merge in your pull requests and hopefully build a huge library of RabbitMQ examples that can help everyone. There are already Ruby versions of the examples merged in!</p>

<p>So if those aren't reasons enough to give RabbitMQ in Action a shot…how about a 37% discount just because you read this blog? <img src='https://www.rabbitmq.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>

<p>Save 37% on RabbitMQ in Action with Promotional Discount Code <em><strong>12rmqb</strong></em> when you checkout at <a href="http://manning.com/videla">the Manning web site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2012/05/29/jason-and-alvaros-excellent-rabbit-book/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing RabbitMQ-Web-Stomp</title>
		<link>http://www.rabbitmq.com/blog/2012/05/14/introducing-rabbitmq-web-stomp/</link>
		<comments>http://www.rabbitmq.com/blog/2012/05/14/introducing-rabbitmq-web-stomp/#comments</comments>
		<pubDate>Mon, 14 May 2012 09:54:41 +0000</pubDate>
		<dc:creator>Marek Majkowski</dc:creator>
				<category><![CDATA[New Features]]></category>
		<category><![CDATA[web messaging]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=284</guid>
		<description><![CDATA[For quite a while here, at RabbitMQ headquarters, we were struggling to find a good way to expose messaging in a web browser. In the past we tried many things ranging from the old-and-famous JsonRPC plugin (which basically exposes AMQP via AJAX), to Rabbit-Socks (an attempt to create a generic protocol hub), to the management [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.rabbitmq.com/wp-uploads/2012/05/web-stomp.png"><img src="http://www.rabbitmq.com/wp-uploads/2012/05/web-stomp-300x162.png" alt="" title="web-stomp" width="300" height="162" class="aligncenter size-medium wp-image-296" /></a></p>

<p>For quite a while here, at RabbitMQ headquarters, we were struggling to
find a good way to expose messaging in a web browser. In the past we tried many
things ranging from the old-and-famous JsonRPC plugin (which basically
exposes AMQP via AJAX), to Rabbit-Socks (an attempt to create a generic
protocol hub), to the management plugin (which can be used for basic
things like sending and receiving messages from the browser).</p>

<p>Over time we've learned that the messaging on the web is very different
to what we're used to. None of our attempts really addressed
that, and it is likely that messaging on the web will not be a fully
solved problem for some time yet.</p>

<p>That said, there is a simple thing RabbitMQ users keep on asking
about, and although not perfect, it's far from the worst way do messaging
in the browser: exposing STOMP through Websockets.</p>

<p><span id="more-284"></span></p>

<h1>STOMP + Websockets</h1>

<p>We're delighted to introduce a new plugin for RabbitMQ:</p>

<ul>
<li><a href="https://github.com/rabbitmq/rabbitmq-web-stomp">RabbitMQ-Web-Stomp</a></li>
</ul>

<p>It is basically a bridge between <a href="https://github.com/rabbitmq/rabbitmq-stomp">RabbitMQ-STOMP</a>
plugin and a Websockets server (<a href="http://sockjs.org">SockJS</a>). Hopefully, it is a decent solution
for a set of rabbit-on-the-web use cases.</p>

<h1>What it actually does</h1>

<h3>Within RabbitMQ </h3>

<p>RabbitMQ-Web-Stomp is a simple beast. It takes the STOMP
protocol as provided by the RabbitMQ-STOMP plugin and exposes it using
the SockJS server.</p>

<h3>Wire protocol</h3>

<p>One can connect to the SockJS endpoint from any browser using the reliable
SockJS protocol. This will work even in browsers that don't support
native websockets or in environments behind broken proxies that block non-http
transports.</p>

<p>Alternatively, for users that don't need this level of sophistication,
SockJS exposes a raw websockets url that can be accessed directly from
a recent, websocket-capable browser.</p>

<h3>In the browser</h3>

<p>Within the browser, the connection to SockJS endpoint is basically
a raw STOMP connection. You can send and receive normal STOMP frames.</p>

<p>Any decent javascript STOMP library should be able to handle that.
For our examples we're using the <a href="https://github.com/jmesnil/stomp-websocket/">stomp-websocket</a> library by <a href="https://github.com/jmesnil">Jeff Mesnil</a> and <a href="https://github.com/progrium">Jeff Lindsay</a>.</p>

<p>We use this code in the examples:</p>

<pre><code>&lt;script src="http://cdn.sockjs.org/sockjs-0.3.min.js"&gt;&lt;/script&gt;
&lt;script src="stomp.js"&gt;&lt;/script&gt;
&lt;script&gt;
   WebSocketStompMock = SockJS;

    var client = Stomp.client('http://127.0.0.1:55674/stomp');
    [...]
</code></pre>

<h1>Installation</h1>

<p><a href="https://github.com/rabbitmq/rabbitmq-web-stomp">Rabbitmq-Web-Stomp</a> is an experimental plugin.
It's not distributed with vanilla RabbitMQ releases; you need to install it manually.</p>

<ol>
<li>You need at least Erlang R14 (<a href="http://www.rabbitmq.com/which-erlang.html">more info</a>).</li>
<li>You need <a href="http://www.rabbitmq.com/download.html">Rabbitmq-server 2.8.2</a> installed</li>
<li>Grab the needed erlang plugin .ez files:

<pre><code>wget \
  http://www.rabbitmq.com/releases/plugins/v2.8.2-web-stomp-preview/cowboy-0.5.0-rmq2.8.2-git4b93c2d.ez \
  http://www.rabbitmq.com/releases/plugins/v2.8.2-web-stomp-preview/sockjs-0.2.1-rmq2.8.2-gitfa1db96.ez \
  http://www.rabbitmq.com/releases/plugins/v2.8.2-web-stomp-preview/rabbitmq_web_stomp-2.8.2.ez \

http://www.rabbitmq.com/releases/plugins/v2.8.2-web-stomp-preview/rabbitmq_web_stomp_examples-2.8.2.ez</code></pre></li>

<li>Next, copy them to the <a href="http://www.rabbitmq.com/plugins.html#installing-plugins">plugins directory</a>. For example, on my Ubuntu box this will be:

<pre><code>sudo cp *.ez /usr/lib/rabbitmq/lib/rabbitmq_server-2.8.2/plugins
</code></pre></li>
<li>Now, you're ready to enable them using <a href="http://www.rabbitmq.com/plugins.html">rabbitmq-plugins</a>:

<pre><code>sudo rabbitmq-plugins enable rabbitmq_web_stomp
sudo rabbitmq-plugins enable rabbitmq_web_stomp_examples
</code></pre></li>
<li>Restart the rabbitmq server. On ubuntu:

<pre><code>sudo /etc/init.d/rabbitmq-server restart
</code></pre></li>
</ol>

<p>As you may have noticed, we enabled two plugins:</p>

<ul>
<li>First, <a href="https://github.com/rabbitmq/rabbitmq-web-stomp">RabbitMQ-web-stomp</a>, which is the main
plugin. It exposes SockJS endpoint on port 55674, like: <a href="http://127.0.0.1:55674/stomp">http://127.0.0.1:55674/stomp</a>.</li>
<li>Second,
<a href="https://github.com/rabbitmq/rabbitmq-web-stomp-examples">RabbitMQ-web-stomp-examples</a>, which
only hosts a few javascript and html files with examples. This is accessible under:
<a href="http://127.0.0.1:55670/">http://127.0.0.1:55670/</a>.</li>
</ul>

<p>Keep in mind, that RabbitMQ-web-stomp depends on <a href="http://www.rabbitmq.com/stomp.html">RabbitMQ-STOMP</a> which by default will bind to port 61613.</p>

<h1>The usage</h1>

<p>If you enabled RabbitMQ-web-stomp-examples plugin, you should be able
to instantly run two examples prepared by us. Just open a web
browser at <a href="http://127.0.0.1:55670/">http://127.0.0.1:55670/</a>.</p>

<ul>
<li><a href="http://127.0.0.1:55670/web-stomp-examples/echo.html">"echo"</a> - shows how to use STOMP to do
simple message broadcasting (<a href="https://github.com/rabbitmq/rabbitmq-web-stomp-examples/blob/master/priv/echo.html">source</a>)<a href="http://www.rabbitmq.com/wp-uploads/2012/05/web-stomp-echo.png"><img src="http://www.rabbitmq.com/wp-uploads/2012/05/web-stomp-echo-300x141.png" alt="" title="web-stomp-echo" width="300" height="141" class="aligncenter size-medium wp-image-290" /></a></li>
<li><a href="http://127.0.0.1:55670/web-stomp-examples/bunny.html">"bunny"</a> - example of a simple
collaboration canvas painting app (<a href="https://github.com/rabbitmq/rabbitmq-web-stomp-examples/blob/master/priv/bunny.html">source</a>)<a href="http://www.rabbitmq.com/wp-uploads/2012/05/web-stomp-bunny1.png"><img src="http://www.rabbitmq.com/wp-uploads/2012/05/web-stomp-bunny1-300x183.png" alt="" title="web-stomp-bunny" width="300" height="183" class="aligncenter size-medium wp-image-294" /></a></li>
</ul>

<h1>Summary</h1>

<p>RabbitMQ-web-stomp is quite a simple plugin, but opens wide possibilities,
exposing the STOMP protocol to the browser.</p>

<p>Like always, feedback welcome. We're also looking for inspiration for
more examples!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2012/05/14/introducing-rabbitmq-web-stomp/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Some queuing theory: throughput, latency and bandwidth</title>
		<link>http://www.rabbitmq.com/blog/2012/05/11/some-queuing-theory-throughput-latency-and-bandwidth/</link>
		<comments>http://www.rabbitmq.com/blog/2012/05/11/some-queuing-theory-throughput-latency-and-bandwidth/#comments</comments>
		<pubDate>Fri, 11 May 2012 11:17:29 +0000</pubDate>
		<dc:creator>Matthew Sackman</dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[New Features]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=276</guid>
		<description><![CDATA[You have a queue in Rabbit. You have some clients consuming from that queue. If you don't set a QoS setting at all (basic.qos), then Rabbit will push all the queue's messages to the clients as fast as the network and the clients will allow. The consumers will balloon in memory as they buffer all [...]]]></description>
			<content:encoded><![CDATA[<p>You have a queue in Rabbit. You have some clients consuming from that
queue. If you don't set a QoS setting at all (<code>basic.qos</code>), then
Rabbit will push all the queue's messages to the clients as fast as
the network and the clients will allow. The consumers will balloon in
memory as they buffer all the messages in their own RAM. The queue may
appear empty if you ask Rabbit, but there may be millions of messages
unacknowledged as they sit in the clients, ready for processing by the
client application. If you add a new consumer, there are no messages
left in the queue to be sent to the new consumer. Messages are just
being buffered in the existing clients, and may be there for a long
time, even if there are other consumers that become available to
process such messages sooner. This is rather sub optimal.</p>

<p>So, the default QoS <code>prefetch</code> setting gives clients an <em>unlimited</em>
buffer, and that can result in poor behaviour and performance. But
what should you set the QoS <code>prefetch</code> buffer size to? The goal is to
keep the consumers saturated with work, but to minimise the client's
buffer size so that more messages stay in Rabbit's queue and are thus
available for new consumers or to just be sent out to consumers as
they become free.<span id="more-276"></span></p>

<p>Let's say it takes 50ms for Rabbit to take a message from this queue,
put it on the network and for it to arrive at the consumer. It takes
4ms for the client to process the message. Once the consumer has
processed the message, it sends an <code>ack</code> back to Rabbit, which takes a
further 50ms to be sent to and processed by Rabbit. So we have a total
round trip time of 104ms. If we have a QoS <code>prefetch</code> setting of 1
message then Rabbit won't sent out the next message until after this
round trip completes. Thus the client will be busy for only 4ms of
every 104ms, or 3.8% of the time. We want it to be busy 100% of the
time.</p>

<p><a href="http://www.rabbitmq.com/wp-uploads/2012/05/qos.svg"><img src="http://www.rabbitmq.com/wp-uploads/2012/05/qos.svg" alt="Consuming from a Queue" title="Consuming from a Queue" class="aligncenter size-full wp-image-279" /></a></p>

<p>If we do <em>total round trip time</em> / <em>processing time on the client for
each message</em>, we get <code>104 / 4 = 26</code>. If we have a QoS <code>prefetch</code> of
26 messages this solves our problem: assume that the client has 26
messages buffered, ready and waiting for processing. (This is a
sensible assumption: once you set <code>basic.qos</code> and then <code>consume</code> from
a queue, Rabbit will send as many messages as it can from the queue
you've subscribed to to the client, up to the QoS limit. If you assume
messages aren't very big and bandwidth is high, it's likely Rabbit
will be able to send messages to your consuming client faster than
your client can process them. Thus it's reasonable (and simpler) to do
all the maths from the assumption of a full client-side buffer.) If
each message takes 4ms of processing to deal with then it'll take a
total of <code>26 * 4 = 104ms</code> to deal with the entire buffer. The first
4ms is the client processing of the first message. The client then
issues an <code>ack</code> and goes on to process the next message from the
buffer. That ack takes 50ms to get to the broker. The broker than
issues a new message to the client, which takes 50ms to get there, so
by the time 104ms has passed and the client has finished processing
its buffer, the next message from the broker has already arrived and
is ready and waiting for the client to process it. Thus the client
remains busy all the time: having a bigger QoS <code>prefetch</code> will not
make it go faster; but we minimise the buffer size and thus latency of
messages in the client: messages are buffered by the client for no
longer than they need to be in order to keep the client saturated with
work. In fact, the client is able to fully drain the buffer before the
next message arrives, thus the buffer actually stays empty.</p>

<p>This solution is absolutely fine, provided processing time and network
behaviour remains the same. But consider what happens if suddenly the
network halves in speed: your <code>prefetch</code> buffer is no longer big
enough and now the client will sit idle, waiting for new messages to
arrive as the client is able to process messages faster than Rabbit
can supply fresh messages.</p>

<p>To address this problem, we might just decide to double (or nearly
double) the QoS <code>prefetch</code> size. If we push it to 51 from 26, then if
the client processing remains at 4ms per message, we now have <code>51 * 4
= 204ms</code> of messages in the buffer, of which 4ms will be spent
processing a message, leaving 200ms for the sending an ack back to
Rabbit and receiving the next message. Thus we can now cope with the
network halving in speed.</p>

<p>But if the network's performing normally, doubling our QoS <code>prefetch</code>
now means each message will sit in the client side buffer for a while,
instead of being processed immediately upon arrival at the
client. Again, starting from a full buffer of now 51 messages we know
that new messages will start appearing at the client 100ms after the
client finishes processing the first message. But in those 100ms, the
client will have processed <code>100 / 4 = 25</code> messages out of the 50
available. Which means as a new message arrives at the client, it'll
be added to the end of the buffer as the client removes from the head
of the buffer. The buffer will thus always stay <code>50 - 25 = 25</code>
messages long and every message will thus sit in the buffer for <code>25 *
4 = 100ms</code>, increasing the latency between Rabbit sending it to the
client and the client starting to process it from 50ms to 150ms.</p>

<p>Thus we see that increasing the <code>prefetch</code> buffer so that the client
can cope with deteriorated network performance whilst keeping the
client busy, substantially increases the latency when the network is
performing normally.</p>

<p>Equally, rather than the network's performance deteriorating, what
happens if the client starts taking 40ms to process each message
rather than 4ms? If the queue in Rabbit was previously at a steady
length (i.e. ingress and egress rates were the same), it'll now start
growing rapidly, as the egress rate has dropped to a tenth of what it
was. You might decide to try and work through this growing backlog by
adding more consumers, but there are messages now being buffered by
the existing clients. Assuming the original buffer size of 26
messages, the client will spend 40ms processing the first message,
will then send the ack back to Rabbit and move onto the next
message. The ack still takes 50ms to get to Rabbit and a further 50ms
for Rabbit to send out a new message, but in that 100ms, the client
has only worked through <code>100 / 40 = 2.5</code> further messages rather than
the remaining 25 messages. Thus the buffer is at this point <code>25 - 3 =
22</code> messages long. The new message arriving from Rabbit, rather than
being processed immediately, now sits in 23rd place, behind 22 other
messages still waiting to be processed, and will not be touched by the
client for a further <code>22 * 40 = 880ms</code>. Given the network delay from
Rabbit to the client is only 50ms, this additional 880ms delay is now
95% of the latency (<code>880 / (880 + 50) = 0.946</code>).</p>

<p>Even worse, what happens if we doubled the buffer size to 51 messages
in order to cope with network performance degradation? After the first
message has been processed, there will be 50 further messages buffered
in the client. 100ms later (assuming the network is running normally),
a new message will arrive from Rabbit, and the client will be half way
through processing the 3rd of those 50 messages (the buffer will now
be 47 messages long), thus the new message will be 48th in the buffer,
and will not be touched for a further <code>47 * 40 = 1880ms</code>. Again, given
the network delay of getting the message to the client is only 50ms,
this further 1880ms delay now means client side buffering is
responsible for over 97% of the latency (<code>1880 / (1880 + 50) =
0.974</code>). This may very well be unacceptable: the data may only be
valid and useful if it's processed promptly, not some 2 seconds after
the client received it! If other consuming clients are idle, there's
nothing they can do: once Rabbit has sent a message to a client, the
message is the client's responsibility until it acks or rejects the
message. Clients can't steal messages from each other once the message
has been sent to a client. What you want is for clients to be kept
busy, but for clients to buffer as few messages as possible so that
messages are not delayed by client-side buffers and thus new consuming
clients can be quickly fed with messages from Rabbit's queue.</p>

<p>So, too small a buffer results in clients going idle if the network
gets slower, but too big a buffer results in lots of extra latency if
the network performs normally, and huge amounts of extra latency if
the client suddenly starts taking longer to process each message than
normal. It's clear that what you really want is a varying buffer
size. These problems are common across network devices and have been
the subject of much study. <em>Active Queue Management</em> algorithms seek
to try and drop or reject messages so that you avoid messages sitting
in buffers for long periods of time. The lowest latency is achieved
when the buffer is kept empty (each message suffers network latency
only and does not sit around in a buffer at all) and buffers are there
to absorb spikes. <a href="http://gettys.wordpress.com/">Jim Gettys</a> has been
working on this problem from the point of view of network routers:
differences between performance of the LAN and the WAN suffer exactly
the same sorts of problems. Indeed whenever you have a buffer between
a producer (in our case Rabbit) and a consumer (the client-side
application logic) where the performance of both sides can vary
dynamically, you will suffer these sorts of problems. Recently a new
algorithm called
<a href="https://queue.acm.org/detail.cfm?id=2209336">Controlled Delay</a> has
been published which
<a href="http://arstechnica.com/information-technology/2012/05/codel-buffer-management-could-solve-the-internets-bufferbloat-jams/">appears to work well</a>
in solving these problems.</p>

<p>The authors claim that their <em>CoDel</em> ("coddle") algorithm is a "knob
free" algorithm. This is a bit of a lie really: there are two knobs
and they do need setting appropriately. But they don't need changing
every time performance changes, which is a massive benefit. I have
<a href="https://gist.github.com/2658712">implemented this algorithm</a> for our
AMQP Java Client as a variant of the QueueingConsumer. Whilst the
original algorithm is aimed at the TCP layer, where it's valid to just
drop packets (TCP itself will take care
of re-transmission of lost packets), in AMQP that's not so polite! As a result,
my implementation uses Rabbit's <code>basic.nack</code> extension to explicitly
return messages to the queue so they can be processed by others.</p>

<p><a href="https://gist.github.com/2658727">Using it is pretty much the same</a> as
the normal QueueingConsumer except that you should provide three extra
parameters to the constructor to get the best performance.</p>

<ol>
<li>The first is <code>requeue</code> which says whether, when messages are
nacked, should they be requeued or discarded. If false, they will
be discarded which may trigger the dead letter exchange mechanisms
if they're set up.</li>
<li>The second is the <code>targetDelay</code> which is the acceptable time in
milliseconds for messages to wait in the client-side QoS <code>prefetch</code>
buffer.</li>
<li>The third is the <code>interval</code> and is the expected worst case
processing time of one message in milliseconds. This doesn't have
to be spot on, but within an order of magnitude certainly helps.</li>
</ol>

<p>You should still set a QoS <code>prefetch</code> size appropriately. If you do
not, what is likely is that the client will be sent a lot of messages,
and the algorithm will then have to return them to Rabbit if they sit
in the buffer for too long. It's easy to end up with a lot of extra
network traffic as messages are returned to Rabbit. The CoDel
algorithm is meant to only start dropping (or rejecting) messages once
performance diverges from the norm, thus a worked example might help.</p>

<p>Again, assume network traversal time in each direction of 50ms, and we
expect the client to spend 4ms on average processing each message, but
this can spike to 20ms. We thus set the <code>interval</code> parameter of CoDel
to 20. Sometimes the network halves in speed, so the traversal time
can be 100ms in each direction. To cater for that, we set the
<code>basic.qos prefetch</code> to <code>204 / 4 = 51</code>. Yes, this means that the
buffer will remain 25 messages long most of the time when the network
is running normally (see workings earlier), but we decide that's
OK. Each message will thus sit in the buffer for an expected <code>25 * 4 =
100ms</code>, so we set the <code>targetDelay</code> of CoDel to 100.</p>

<p>When things are running normally, CoDel should not get in the way, and
few if any messages should be being nacked. But should the client
start processing messages more slowly than normal, CoDel will spot
that messages have been buffered by the client for too long, and will
return those messages to the queue. If those messages are requeued
then they will become available for delivery to other clients.</p>

<p>This is very much experimental at the moment, and it's possible to see
reasons why CoDel isn't as appropriate for dealing with AMQP messages
as it is for plain IP. It's also worth remembering that requeuing
messages via nacks is a fairly expensive operation, so it's a good
idea to set the parameters of CoDel to ensure in normal operation very
few if any messages are being nacked. The management plugin is an easy
way to inspect how many messages are being nacked. As ever, comments,
feedback and improvements are most welcome!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2012/05/11/some-queuing-theory-throughput-latency-and-bandwidth/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>RabbitMQ Performance Measurements, part 2</title>
		<link>http://www.rabbitmq.com/blog/2012/04/25/rabbitmq-performance-measurements-part-2/</link>
		<comments>http://www.rabbitmq.com/blog/2012/04/25/rabbitmq-performance-measurements-part-2/#comments</comments>
		<pubDate>Wed, 25 Apr 2012 13:47:31 +0000</pubDate>
		<dc:creator>Simon MacMullen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[charts]]></category>
		<category><![CDATA[flow control]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=266</guid>
		<description><![CDATA[Welcome back! Last time we talked about flow control and latency; today let's talk about how different features affect the performance we see. Here are some simple scenarios. As before, they're all variations on the theme of one publisher and one consumer publishing as fast as they can. Some Simple Scenarios auto-ack This first scenario [...]]]></description>
			<content:encoded><![CDATA[<p><link href="/resources/performance-blog/perf.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="/resources/performance-blog/lib/excanvas.min.js"></script><![endif]--></p>

<script language="javascript" type="text/javascript" src="/resources/performance-blog/lib/jquery.min.js"></script>

<script language="javascript" type="text/javascript" src="/resources/performance-blog/lib/jquery.flot.min.js"></script>

<script language="javascript" type="text/javascript" src="/resources/performance-blog/perf.js"></script>

<script language="javascript" type="text/javascript" src="/resources/performance-blog/json2.js"></script>

<p>
  Welcome back! <a href="/blog/2012/04/17/rabbitmq-performance-measurements-part-1/">Last time</a> we talked about flow control and
  latency; today let's talk about how different features affect
  the performance we see. Here are some simple scenarios. As
  before, they're all variations on the theme of one publisher and
  one consumer publishing as fast as they can.
</p>

<p><span id="more-266"></span></p>

<h2>Some Simple Scenarios</h2>

<div class="box">
  <div class="summary" scenario="no-ack">auto-ack</div>
  <div class="small-chart"
       type="time"
       x-axis="time (s)"
       y-axis=""
       scenario="no-ack"></div>
  <p>
    This first scenario is the simplest - just one producer and
    one consumer. So we have a baseline.
  </p>
</div>

<div class="box">
  <div class="summary" scenario="no-consume">no-consume</div>
  <div class="small-chart"
       type="time"
       x-axis="time (s)"
       y-axis=""
       scenario="no-consume"></div>
  <p>
    Of course we want to produce impressive figures. So we can go
    a bit faster than that - if we don't consume anything then we
    can publish faster.
  </p>
</div>

<div class="box">
  <div class="summary" scenario="headline-publish" mode="send">max publish</div>
  <div class="small-chart"
       type="time"
       x-axis="time (s)"
       y-axis=""
       scenario="headline-publish"></div>
  <p>
    This uses a couple of the cores on our server - but not all of
    them. So for the best headline-grabbing rate, we start a
    number of parallel producers, all publishing into nothing.
  </p>
</div>

<div class="box">
  <div class="summary" scenario="headline-consume" mode="recv">max consume</div>
  <div class="small-chart"
       type="time"
       x-axis="time (s)"
       y-axis=""
       scenario="headline-consume"></div>
  <p>
    Of course, consuming is rather important! So for the headline
    consuming rate, we publish to a large number of consumers in
    parallel.
  </p>
</div>

<p>
  Of course to some extent this quest for large numbers is a bit
  silly, we're more interested in relative performance. So let's
  revert to one producer and one consumer.
</p>

<div class="box">
  <div class="summary" scenario="no-ack-mandatory">mandatory</div>
  <div class="small-chart" type="time" x-axis="time (s)" y-axis=""
       scenario="no-ack-mandatory"></div>
  <p>
    Now let's try publishing with the mandatory flag set. We drop
    to about 40% of the non-mandatory rate. The reason for this is
    that the channel we're publishing to can't just asynchronously
    stream messages at queues any more; it synchronously checks
    with the queues to make sure they're still there. (Yes, we
    could probably make mandatory publishing faster, but it's not
    very heavily used.)
  </p>
</div>

<div class="box">
  <div class="summary" scenario="no-ack-immediate">immediate</div>
  <div class="small-chart" type="time" x-axis="time (s)" y-axis=""
       scenario="no-ack-immediate"></div>
  <p>
    The immediate flag gives us almost exactly the same drop in
    performance. This isn't hugely surprising - it has to make the
    same synchronous check with the queue.
  </p>
</div>

<div class="box">
  <div class="summary" scenario="ack">ack</div>
  <div class="small-chart" type="time" x-axis="time (s)" y-axis=""
       scenario="ack"></div>
  <p>
    Scrapping the rarely-used mandatory and immediate flags, let's
    try turning on acknowledgements for delivered messages. We still
    see a performance drop compared to delivering without
    acknowledgements (the server has to do more bookkeeping after
    all) but it's less noticeable.
  </p>
</div>

<div class="box">
  <div class="summary" scenario="ack-confirm">ack-confirm</div>
  <div class="small-chart" type="time" x-axis="time (s)" y-axis=""
       scenario="ack-confirm"></div>
  <p>
    Now we turn on publish confirms as well. Performance drops a
    little more but we're still at over 60% the speed of neither
    acks nor confirms.
  </p>
</div>

<div class="box">
  <div class="summary"
       scenario="ack-confirm-persist">a-c-persist</div>
  <div class="small-chart" type="time" x-axis="time (s)" y-axis=""
       scenario="ack-confirm-persist"></div>
  <p>
    Finally, we enable message persistence. The rate becomes much
    lower, since we're throwing all those messages at the disk as
    well.
  </p>
</div>

<h2>Message Sizes</h2>

<p>
  Notably, all the messages we've been sending until now have only
  been a few bytes long. There are a couple of reasons for this:
</p>

<ul>
  <li>Quite a lot of the work done by RabbitMQ is per-message, not
    per-byte-of-message.</li>
  <li>It's always nice to look at big numbers.</li>
</ul>

<p>
  But in the real world we will often want to send bigger
  messages. So let's look at the next chart:
</p>

<h3>1 -> 1 sending rate message sizes</h3>

<div class="chart"
     type="x-y"
     scenario="message-sizes-large"
     x-key="minMsgSize"
     plot-keys="send-msg-rate send-bytes-rate"
     x-axis="message size (bytes)"
     y-axis="rate (msg/s)"
     y-axis2="rate (bytes/s)"
     legend="ne"></div>

<p>
  Here (again) we're sending unacked / unconfirmed messages as
  fast as possible, but this time we vary the message size. We
  can see that (of course) the message rate drops further as the
  size increases, but the actual number of bytes sent increases as
  we have less and less routing overhead.
</p>

<p>
  So how does the message size affect horizontal scaling? Let's
  vary the number of producers with different message sizes. Just
  for a change, in this test we're not going to have any consumers
  ar all.
</p>

<h3>n -> 0 sending msg rate vs number of producers, for various message sizes</h3>

<div class="chart"
     type="series"
     scenario="message-sizes-and-producers"
     x-key="producerCount"
     x-axis="producers"
     y-axis="rate (msg/s)"
     plot-key="send-msg-rate"
     series-key="minMsgSize"></div>

<h3>n -> 0 sending bytes rate vs number of producers, for various message sizes</h3>

<div class="chart"
     type="series"
     scenario="message-sizes-and-producers"
     x-key="producerCount"
     x-axis="producers"
     y-axis="rate (bytes/s)"
     plot-key="send-bytes-rate"
     series-key="minMsgSize"></div>

<p>
  In these tests we can see that for small messages it only takes
  a couple of producers to reach an upper bound on how many
  messages we can publish, but that for larger messages we need
  more producers to use the available bandwidth.
</p>

<p>
  Another frequently confusing issue is performance around
  consumers with a prefetch count. RabbitMQ (well, AMQP) defaults
  to sending all the messages it can to any consumer that looks
  ready to accept them. The maximum number of these unacknowledged
  messages per channel can be limited by setting the prefetch
  count. However, small prefetch counts can hurt performance
  (since we can be waiting for acks to arrive before sending out
  more messages).
</p>

<p>
  So let's have a look at prefetch count and, while we're there,
  also consider the number of consumers consuming from a single
  queue. This chart contains some deliberately absurd extremes.
</p>

<h3>1 -> n recving rate vs consumer count / prefetch count</h3>

<div class="chart"
     type="series"
     scenario="consumers"
     x-key="consumerCount"
     x-axis="number of consumers"
     x-axis-log="true"
     y-axis="rate (msg/s)"
     legend="ne"
     plot-key="recv-msg-rate"
     series-key="prefetchCount"></div>

<p>
  The first thing to notice is that tiny prefetch counts really
  hurt performance. Note the large difference in performance
  between prefetch = 1 and prefetch = 2! But we also get into
  diminishing returns - notice that the difference between
  prefetch = 20 and prefetch = 50 is hard to see, and the
  difference between prefetch = 50 and prefetch = 10000 is almost
  invisible. Of course, this is because for our particular network
  link prefetch = 50 already ensures that we never starve the
  consumer while waiting for acks. Of course, this test was run
  over a low latency link - more latent links will benefit from a
  higher prefetch count.
</p>

<p>
  The second thing to notice is that when we have a small number
  of consumers, adding one more will increase performance (we get
  more parallellism). And with a tiny prefetch count, increasing
  consumers even up to a large number has benefits (since each
  individual consumer spends much of its time starved). But when
  we have a larger prefetch count, increasing the number of
  consumers is not so helpful, since even a small number can kept
  busy enough to max out our queue, but the more consumers we have
  the more work RabbitMQ has to do to keep track of all of them.
</p>

<h2>Large queues</h2>

<p>
  All the examples we've looked at so far have one thing in
  common: very few messages actually get queued. In general we've
  looked at scenarios where messages get consumed as quickly as
  they get produced, and thus each queue has an average length of
  0.
</p>

<p>
  So what happens whe queues get big? When queues are small(ish)
  they will reside entirely within memory. Persistent messages
  will also get written to disc, but they will only get read again
  if the broker restarts.
</p>

<p>
  But when queues get larger, they will get paged to disc,
  persistent or not. In this case performance can take a hit as
  suddenly we need to access the disc to send messages to
  consumers. So let's run a test: publish a lot of non-persistent
  messages to a queue, and then consume them all.
</p>

<h3>Queue load / drain 500k messages</h3>

<div class="chart"
     type="time"
     x-axis="time (s)"
     y-axis="rate (msg/s)"
     scenario="fill-drain-small-queue"></div>

<p>
  In this small case we can see fairly consistent performance:
  the messages go into the queue fairly quickly and then come out
  even more quickly.
</p>

<h3>Queue load / drain 10M messages</h3>

<div class="chart"
     type="time"
     x-axis="time (s)"
     y-axis="rate (msg/s)"
     scenario="fill-drain-large-queue"></div>

<p>
  But when we have a larger queue we see that the performance
  varies a lot more. We see that when loading the queue we
  initially get a very high throughput, then a pause while some of
  the queue is paged out to disc, then a more consistent lower
  throughput. Similarly when draining the queue we see a much
  lower rate when pulling the messages from disc.
</p>

<p>
  Performance of disc-bound queues is a complex topic -
  see <a href="http://www.rabbitmq.com/blog/2011/10/27/performance-of-queues-when-less-is-more/">Matthew's
    blog post on the subject</a> for some more talk on the subject.
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2012/04/25/rabbitmq-performance-measurements-part-2/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>London Realtime hackweekend</title>
		<link>http://www.rabbitmq.com/blog/2012/04/17/london-realtime-hackweekend/</link>
		<comments>http://www.rabbitmq.com/blog/2012/04/17/london-realtime-hackweekend/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 14:49:08 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=225</guid>
		<description><![CDATA[Over the weekend, RabbitMQ co-sponsored London Realtime, two nights and two days of unadulterated hackery. It was all put on by the apparently indefatigable* crew at GoSquared, a very impressive debut effort. As a co-sponsor we had one of the iPad prizes to award. We decided to allow hacks that used one or more of [...]]]></description>
			<content:encoded><![CDATA[<p>Over the weekend, RabbitMQ co-sponsored <a href="http://londonrealtime.co.uk">London Realtime</a>, two nights and two days of unadulterated hackery. It was all put on by the apparently indefatigable<sup><a href="http://www.youtube.com/watch?v=p2EE7acJv1o&amp;feature=player_embedded#t=120s">*</a></sup> crew at <a href="http://www.gosquared.com/">GoSquared</a>, a very impressive debut effort.</p>

<p><a href="http://www.rabbitmq.com/wp-uploads/2012/04/sockjs-rabbit-cf.png"><img src="http://www.rabbitmq.com/wp-uploads/2012/04/sockjs-rabbit-cf.png" alt="" title="sockjs-rabbit-cf" width="300" class="aligncenter size-full wp-image-221" /></a></p>

<p>As a co-sponsor we had one of the iPad prizes to award. We decided to allow hacks that used one or more of <a href="http://www.rabbitmq.com">RabbitMQ</a>, <a href="http://www.sockjs.org/">SockJS</a>, or <a href="http://www.cloudfoundry.com">Cloud Foundry</a>. This meant that about half of the twenty-seven hacks were eligible when it came to judging, making the choice rather difficult.
<span id="more-225"></span></p>

<p>In the end we chose <strong><a href="http://youchoose.cloudfoundry.com">YouChoose</a></strong>, which uses <strong>SockJS</strong> and is hosted on <strong>CloudFoundry</strong>. The idea was nifty, and the hack complete and well-executed; and it let one of the judges, who shall remain unnamed, subject the audience to the Titanic theme (until they worked out how to collectively vote it off). Empowering stuff.</p>

<p><a href="http://www.flickr.com/photos/olly285/6938424280/" title="IMG_5061.jpg by Olly Plumstead, on Flickr"><img src="http://farm8.staticflickr.com/7084/6938424280_e32169a5e0.jpg" width="500" height="333" alt="IMG_5061.jpg" class="aligncenter"></a>
<br/><p class="aligncenter"><em>(photo by <a href="http://www.flickr.com/photos/olly285/">Olly Plumstead</a>)</em></p></p>

<p>All the hacks were imaginative and almost all made it to a working demo stage -- which was pretty amazing (or perhaps explained by) considering the lack of sleep some people were suffering on Sunday.</p>

<p>Among our favourites were: <strong>Err</strong>, microgames with location-based matchmaking (one of the games is "run away as fast as you can"); <strong>The Worm</strong>, a live popularity chart with optional rageface meter; and <strong>Support Net</strong>, a site and mobile app for people quitting smoking.</p>

<p>Full coverage of the event is over on <a href="http://www.gosquared.com/liquidicity/archives/2873">GoSquared's blog</a>, including video footage and interviews.</p>

<div id="attachment_252" class="wp-caption aligncenter" style="width: 235px"><a href="http://www.rabbitmq.com/wp-uploads/2012/04/pusherlondondry.jpg"><img src="http://www.rabbitmq.com/wp-uploads/2012/04/pusherlondondry-225x300.jpg" alt="London Dry Gin" title="pusherlondondry" width="225" height="300" class="size-medium wp-image-252" /></a><p class="wp-caption-text">Pusher.com are diversifying</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2012/04/17/london-realtime-hackweekend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RabbitMQ Performance Measurements, part 1</title>
		<link>http://www.rabbitmq.com/blog/2012/04/17/rabbitmq-performance-measurements-part-1/</link>
		<comments>http://www.rabbitmq.com/blog/2012/04/17/rabbitmq-performance-measurements-part-1/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 13:09:13 +0000</pubDate>
		<dc:creator>Simon MacMullen</dc:creator>
				<category><![CDATA[Introductory]]></category>
		<category><![CDATA[charts]]></category>
		<category><![CDATA[flow control]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.rabbitmq.com/blog/?p=227</guid>
		<description><![CDATA[So today I would like to talk about some aspects of RabbitMQ's performance. There are a huge number of variables that feed into the overall level of performance you can get from a RabbitMQ server, and today we're going to try tweaking some of them and seeing what we can see. The aim of this [...]]]></description>
			<content:encoded><![CDATA[<p><link href="/resources/performance-blog/perf.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="/resources/performance-blog/lib/excanvas.min.js"></script><![endif]--></p>

<script language="javascript" type="text/javascript" src="/resources/performance-blog/lib/jquery.min.js"></script>

<script language="javascript" type="text/javascript" src="/resources/performance-blog/lib/jquery.flot.min.js"></script>

<script language="javascript" type="text/javascript" src="/resources/performance-blog/perf.js"></script>

<script language="javascript" type="text/javascript" src="/resources/performance-blog/json2.js"></script>

<p>
  So today I would like to talk about some aspects of RabbitMQ's
  performance. There are a huge number of variables that feed into
  the overall level of performance you can get from a RabbitMQ
  server, and today we're going to try tweaking some of them and
  seeing what we can see.
</p>

<p><span id="more-227"></span></p>

<p>
  The aim of this piece is not to try to convince you that
  RabbitMQ is the fastest message broker in the world - it often
  isn't (although we like to think we're still pretty decent) -
  but to give you some ideas about what sort of performance you
  can expect in different situations.
</p>

<p>
  All the charts and statistics shown were measured on a PowerEdge
  R610 with dual Xeon E5530s and 40GB RAM. Largely because it was
  the fastest machine we had lying around. One major thing that's
  not ideal is we ran the clients on the same machine as the
  server - just due to the limited hardware we had available. We used
  RabbitMQ 2.8.1 (in most cases) and Erlang R15B with HiPE compilation
  enabled.
</p>

<p>
  By the way, the code to produce all these statistics
  is available in branch bug24527 of rabbitmq-java-client
  (although it's currently rather rough) Eventually it will get
  merged to default, and also become easier to work with. We hope.
</p>

<h2>Flow control in RabbitMQ 2.8.0+</h2>

<p>
  But first of all I need to introduce a new feature in RabbitMQ
  2.8.0+ - internal flow control. RabbitMQ is internally made up of
  a number of Erlang processes which pass messages to each
  other. Each process has a <em>mailbox</em> which contains
  messages it has received and not yet handled. And these
  mailboxes can grow to an unbounded size.
</p>

<p>
  What this means is that unless the first process to receive data
  off a network socket is the slowest in the chain, (it's not)
  then when you have a heavily-loaded RabbitMQ server messages can
  build up in process mailboxes forever. Or rather, until we run
  out of memory. Or rather, until the memory alarm goes off. At
  which point the server will stop accepting new messages while it
  sorts itself out.
</p>

<p>
  The trouble is, this can take some time. The following chart
  (the only one in this post made against RabbitMQ 2.7.1) shows a
  simple process that publishes small messages into the broker as
  fast as possible, and also consumes them as fast as possible,
  with acknowledgement, confirms, persistence and so on all
  switched off. We plot the sending rate, the receiving rate, and
  the latency (time taken for a sent message to be received), over
  time. Note that the latency is a logarithmic scale.
</p>

<h3>Simple 1 -> 1 autoack (2.7.1)</h3>

<div class="chart"
     type="time"
     latency="true"
     x-axis="time (s)"
     y-axis="rate (msg/s)"
     y-axis2="latency (μs)"
     file="/resources/performance-blog/results-mini-2.7.1.js"
     scenario="no-ack-long"></div>

<p>
  Ouch! That's rather unpleasant. Several things should be obvious:
</p>

<ul>
  <li>The send rate and receive rate fluctuate quite a lot.</li>
  <li>The send rate drops to zero for two minutes (this is the
    first time the memory alarm went off). In fact the memory alarm
    goes off again at the end.</li>
  <li>The latency increases steadily (and look at the scale - we
    show microseconds, but we could just as easily measure it in
    minutes).</li>
</ul>

<p>
  (The small drop in latency around 440s is due to all the
  messages published before 200s being consumed, and the long gap
  afterwards.)
</p>

<p>
  Of course, this is only the sort of behaviour you would expect
  when stressing a server to the limit. But we're benchmarking -
  we want to do that. And anyway, servers get stressed in
  production too.
</p>

<p>
  So now let's look at the same experiment conducted against a
  RabbitMQ 2.8.1 server:
</p>

<h3>Simple 1 -> 1 autoack (2.8.1)</h3>

<div class="chart"
     type="time"
     latency="true"
     x-axis="time (s)"
     y-axis="rate (msg/s)"
     y-axis2="latency (μs)"
     scenario="no-ack-long"></div>

<p>
  That looks like a much calmer experience! The send rate, receive
  rate and latency are all near-constant. The reason is internal
  flow control. The latency is around 400ms (which is still quite
  high compared to a less loaded server for reasons I'll discuss
  in a minute).
</p>

<p>
  These charts don't show memory consumption, but the story is the
  same - in this circumstance 2.7.1 will eat lots of memory and
  bounce off the memory alarm threshold, and 2.8.1 will use a
  fairly constant, fairly low quantity of memory.
</p>

<p>
  Each process in the chain issues <em>credit</em> to the
  processes that can send messages to it. Processes consume credit
  as they send messages, and issue more credit as they receive
  them. When a process runs out of credit it will stop issuing
  more to its upstream processes. Eventually we reach the process
  which is reading bytes off a network
  socket. When <strong>that</strong> process runs out of credit,
  it stops reading until it gets more. This is the same as when
  the memory alarm goes off for the 2.7.1 broker, except that it
  happens many times per second rather than taking minutes, and we
  control memory use a lot more.
</p>

<p>
  So where does that 400ms latency come from? Well, there are
  still messages queueing up at each stage in the pipeline, so it
  takes a while for a message to get from the beginning to the
  end. That accounts for some of the latency. However, most of it
  comes from an invisible "mailbox" in front of the entire server
  - the TCP buffers provided by the operating system. On Linux
  the OS will allow up to 8MB of messages to back up in the TCP
  stack. 8MB doesn't sound like a lot of course, but we're dealing
  with tiny messages (and each one needs routing decisions,
  permissions check and so on to be made).
</p>

<p>
  But it's important to remember that we tend to see the worst
  latency when running at the limit of what we can do. So here's
  one final chart for this week:
</p>

<h3>1 -> 1 sending rate attempted vs latency</h3>

<div class="chart"
     type="r-l"
     x-axis="rate attempted (msg/s)"
     y-axis="rate (msg/s)"
     scenario="rate-vs-latency"></div>

<p>
  Note that the horizontal axis is no longer time. We're now
  showing the results of many runs like the ones above, with each
  point representing one run.
</p>

<p>
  In the charts above we were running as fast as we can, but here
  we limit the rate at varying points up to the maximum rate we
  can achieve. So the yellow line shows rate attempted vs rate
  achieved - see that it goes most of the way purely 1:1 linearly
  (when we have spare capacity and so if we try to publish faster
  we will succeed) and then stops growing as we reach the limit of
  what we can do.
</p>

<p>
  But look at the latency! With low publishing rates we have
  latency of considerably less than a millisecond. But this drifts
  up as the server gets busier. As we stop being able to publish
  any faster, we hit a wall of latency - the TCP buffers start to
  fill up and soon messages are taking hundreds of milliseconds to
  get through them.
</p>

<p>
  So hopefully we've shown how RabbitMQ 2.8.1 offers much more
  reliable performance when heavily loaded than previous versions,
  and shown how latency can reach for the skies when your message
  broker is overloaded. Tune in next time to see how some
  different ways of using messaging affect performance!
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rabbitmq.com/blog/2012/04/17/rabbitmq-performance-measurements-part-1/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
