I get approximately that performance (4000 messages/s) on 64-bit Windows 7, with v2.7.1 of the RabbitMQ broker running R15B of Erlang, using the loopback network interface, running on a 2.80GHz Xeon with memory bus running at<div>
<br></div><div>Having done some minimal performance testing what is slow is the way I do the BasicPublish.</div><div><br></div><div>What makes this slow is that I've enabled the publisher confirms part of the AMQP protocol - so when I basic.publish a message to the broker, I wait for the broker to 'deal' with the message and send a basic.ack back. This is slow. I did this to take something that is inherently asynchronous (basic.publish at its default is asynchonous, especially the way it handles errors like publishing to a non-existent exchange) and wrap it in a synchronous API.</div>
<div><br></div><div>If you break apart the publishing and consuming I can get ~4000 msg/s publish, and ~65000 msg/s consume without worrying about acking messages:</div><div><br></div><div><div>#define BOOST_ALL_NO_LIB</div>
<div><br></div><div>#include <SimpleAmqpClient/SimpleAmqpClient.h></div><div><br></div><div>#include <iostream></div><div>#include <boost/timer/timer.hpp></div><div>#include <stdlib.h></div><div><br>
</div><div>using namespace AmqpClient;</div><div>int main()</div><div>{</div><div> char* szBroker = getenv("AMQP_BROKER");</div><div> Channel::ptr_t channel;</div><div> if (szBroker != NULL)</div><div> channel = Channel::Create(szBroker);</div>
<div> else</div><div> channel = Channel::Create();</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>channel->DeclareQueue("alanqueue");</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>channel->BindQueue("alanqueue", "amq.direct", "alankey");</div>
<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>BasicMessage::ptr_t msg_in = BasicMessage::Create();</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>msg_in->Body("This is a small message.");</div>
<div><br></div><div> std::cerr << "Sending messages....";</div><div> {</div><div> boost::timer::auto_cpu_timer t;</div><div> for (int i = 0; i < 100000; ++i)</div><div> {</div><div> channel->BasicPublish("amq.direct", "alankey", msg_in);</div>
<div> }</div><div> }</div><div> std::cerr << "done.\n";</div><div><br></div><div> std::cerr << "Receiving messages....";</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>std::string consumer = channel->BasicConsume("alanqueue", "consumertag");</div>
<div> {</div><div> boost::timer::auto_cpu_timer t;</div><div> for (int i = 0; i < 100000; ++i)</div><div> {</div><div> channel->BasicConsumeMessage(consumer);</div><div> }</div><div> }</div><div> std::cerr << "done.\n";</div>
<div>}</div></div><div><br></div><div><br></div><div>Output from this program:</div><div><br></div><div><div>Sending messages.... 24.938781s wall, 0.546003s user + 5.272834s system = 5.818837s CPU (23.3%)</div><div>done.</div>
<div>Receiving messages.... 0.165081s wall, 0.078001s user + 0.078001s system = 0.156001s CPU (94.5%)</div><div>done.</div></div><div><br></div><div>-Alan</div><div><br></div><div><br><div class="gmail_quote">On Thu, Mar 8, 2012 at 8:15 AM, Eric J. Holtman <span dir="ltr"><<a href="mailto:eric@holtmans.com">eric@holtmans.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I've finally gotten everything working inside my<br>
project (Thanks, Alan!).<br>
<br>
I'm trying a small test now where I have one producer<br>
and one consumer on a queue. Running in Release mode<br>
C++ (no debugging), I seem to top out around 3,700<br>
messages/second.<br>
<br>
Is that about what I should expect, or am I doing<br>
something wrong? I thought it should be higher.<br>
<br>
I can believe (but have not yet profiled it) that I'm<br>
losing throughput because of all the std::strings and<br>
shared_ptrs. If that's the case, I think that's just<br>
the price I will have to pay for C++, unless I want<br>
to drop down to using the underlying rabbitmq_c library.<br>
<br>
<br>
<br>
Here's the guts of the producer:<br>
<br>
using namespace AmqpClient;<br>
Channel::ptr_t channel;<br>
channel = Channel::Create();<br>
<br>
channel->DeclareQueue("BasicReturnTestQueue", false, false, false, true);<br>
<br>
const std::string constant ("foo");<br>
try {<br>
for (int i = 0; i < nmsgs; ++i) {<br>
BasicMessage::ptr_t the_message = BasicMessage::Create(constant);<br>
channel->BasicPublish("", "BasicReturnTestQueue", the_message, true,<br>
false);<br>
}<br>
BasicMessage::ptr_t the_message = BasicMessage::Create("quit");<br>
channel->BasicPublish("", "BasicReturnTestQueue", the_message, true,<br>
false);<br>
}<br>
catch (MessageReturnedException& e) {<br>
std::cout << "Message got returned: " << e.what();<br>
std::cout << "\nMessage body: " << e.message()->Body();<br>
}<br>
<br>
<br>
And here's the consumer:<br>
<br>
using namespace AmqpClient;<br>
Channel::ptr_t channel;<br>
channel = Channel::Create();<br>
<br>
channel->DeclareQueue("BasicReturnTestQueue", false, false, false, true);<br>
channel->BasicConsume("BasicReturnTestQueue", "consumer_tag1", true,<br>
true, true, 10);<br>
<br>
<br>
try {<br>
while (1) {<br>
Envelope::ptr_t env;<br>
if (channel->BasicConsumeMessage("consumer_tag1", env, 0)) {<br>
std::string msg = env->Message ()->Body ();<br>
if (msg == "quit") {<br>
return;<br>
}<br>
}<br>
}<br>
}<br>
catch (MessageReturnedException& e)<br>
{<br>
std::cout << "Message got returned: " << e.what();<br>
std::cout << "\nMessage body: " << e.message()->Body();<br>
}<br>
<br>
_______________________________________________<br>
rabbitmq-discuss mailing list<br>
<a href="mailto:rabbitmq-discuss@lists.rabbitmq.com">rabbitmq-discuss@lists.rabbitmq.com</a><br>
<a href="https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss" target="_blank">https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss</a><br>
</blockquote></div><br></div>