[rabbitmq-discuss] request for help!

Tim Fox tim.fox at jboss.com
Mon May 10 14:37:04 BST 2010

I've spent this morning going through the 1.0. PR3 spec, firstly, it's 
considerably simpler than 0.10, which is great news :)

Here's my 2p:

One thing I find quite strange is that the core spec doesn't actually 
seem to mandate any queueing semantics anywhere. I've nothing 
particularly against that - in fact, the idea that a node can do 
different types of ordering is actually quite nice, however it's not a 
queueing protocol. Shouldn't AMQP therefore be renamed to AMTP (Advanced 
Message Transfer Protocol) ? ;)

On a more serious note, my main concerns are mainly around complexity, 
and verbosity of the wire format. The latter I suppose is not completely 
independent from the former.

Regarding complexity. IMO a large part of the complexity in the spec. 
seems to come from the way it tries to provide a once and only once 
delivery guarantee. AIUI the way the spec. implements this guarantee is 
something like the following when transferring a message from A to B:

a) message to be sent from A-->B
b) ack sent back from B-->A
c) "ack of ack" sent from A-->B - now the delivery tag can be removed 
from the senders cache

This results in a complex set of message states, and puts the burden on 
both sides of the link to maintain a map of delivery tags, which would 
also have to be persisted in order to provide once and only delivery 
guarantee in event of failures of node(s). This will also require 
several syncs to storage at each transition (for durable messaging). 
I.e. slow

Perhaps a simpler way of getting the once and only guarantee is to 
forget the delivery tag altogether and allow the sender to specify a 
de-duplication-id - this is just a user generated id - e.g. a String or 
a byte[], (can be generated from user application domain concepts - e.g. 
order number).

When sending a message this id can be specified on the transfer. The 
receiving end can then maintain a de-duplication cache. The 
de-duplication cache can be implemented as a circular buffer which just 
overwrites itself when full (this is what we do in HornetQ for reliable 
bridging between nodes), this means the interaction c) is not necessary 
or can just be sent intermittently to allow the cache to be cleared. The 
de-dup cache still requires syncing to non volatile storage to give the 
once and only once (for durable messages), however it requires less 
writes than the method described in the spec, and it it has one less 
interaction (you can get rid of the "ack of ack")

On recovery after system failure, the sender just blindly sends the 
messages again, on receipt at the server any messages seen before will 
just be rejected. No need for reattaching, sending maps of unsettled 
transfers or other complex stuff like that.

By removing all this delivery tag book-keeping and session re-attachment 
stuff, which seems unnecessary to me, would result in a dramatic 

Regarding verbosity of the wire format for message transfer; if you're 
just passing a 12 byte message (e.g. stock price - 4 byte identifier + 8 
byte price) then the overall encoded size is much higher than 12 bytes.

This will kill performance for small messages, making any AMQP compliant 
implementation unable to compete in the world of lightweight 
publish/subscribe messaging with other, non AMQP implementations which 
don't have to conform to the AMQP wire format and can produce much more 
lightweight encodings. The key to perf with lightweight pub/sub is to 
make the encoded message size as small as possible and cram as many 
messages as you can into single socket writes.

Now, lightweight pub/sub may not be the target domain for AMQP, in which 
case it does not need to worry about it, however if a particular 
messaging system supports multiple protocols including AMQP, it will not 
do much for the adoption of AMQP if the best performance is not 
achievable using the AMQP protocol - users will fall back to using the 
proprietary protocol offered by the vendor.

A short comment on transactions. I have to be honest here, I spent about 
30 mins reading the chapter on transactions several times. I have to say 
at the end of it I am not much further understanding it. :(

However maybe that is moot - a part of me is thinking that transactions 
don't really belong in the core spec. Perhaps the core spec should be 
concerned with allowing the reliable movement of messages between nodes. 
With that in place, transactions could be layered on top in another spec (?)

Sent from my BBC Micro Model B

Tim Fox

HornetQ - putting the buzz in messaging http://hornetq.org
fox at redhat.com

More information about the rabbitmq-discuss mailing list