[rabbitmq-discuss] Ensuring low latency for publishers
ejarendt at gmail.com
Tue Feb 21 17:51:47 GMT 2012
I've made some effort to answer these questions on my own, but I'm
still a bit unsure. I'm designing an application for a webserver that
needs to publish events to a broker as part of the work to render a
request. The information is important, but in the event of a broker
failure or broker throttling, the most important thing is to get the
web request rendered. If that means messages get dropped, that's fine
- the consumers are idempotent and we can replay the messages later if
I'd like this information to be published with as little latency to
the rendering thread as possible, so large delays while publishing
messages (20ms+) aren't acceptable, even if the broker is down or
throttling. Essentially, I want a situation where publishing gets
done, but the publishing process and/or the state of the broker don't
impact the process of rendering the request. I'm using the Java
My first inclination was to put all messages in a blocking queue and
have a single thread dedicated to publishing the contents of that
queue to the broker. If the broker goes down that's ok - a bound on
the queue will make sure we don't exceed the server's heap capacity.
The problem there is that such queues synchronize all writers on a
single lock, and given the high concurrency of the server there could
be a lot of contention. I want to avoid a single point of
There are lock-free queue implementations, but they don't offer an
easy way to implement a size bound.
Rather than queuing locally, isn't RabbitMQ for queueing? So I
figured I could keep a single connection around for all publishers in
the JVM, with one thread responsible for maintaining the connection.
Since the server uses a thread pool to render requests, every thread
can have their own channel in a threadlocal, only creating a new
channel if the underlying connection breaks and is reestablished or
they haven't created one before. If the connection is down when the
rendering thread tries to publish, we'll just drop the message.
Otherwise each rendering thread can publish straight to RabbitMQ.
A couple of questions about doing it this way. First, does publishing
a message require a roundtrip to the broker? I dug around on the
topic and came to some part of the AMQP spec that indicates publishing
is a "cast", not a "call", so it seems like it shouldn't. ACKs come
back asynchronously, so I'm assuming publishing is essentially a 0ms
operation, but I want to be sure. Second, if the broker is throttling
via "TCP backpressure" (which I'm having a hard time finding a good
definition for) will that increase publisher latency? I see that I
can set a socket timeout, but I think that only applies if the broker
is actually down.
More information about the rabbitmq-discuss