[rabbitmq-discuss] SimpleAmqpClient speed?

33 views
Skip to first unread message

Eric J. Holtman

unread,
Mar 8, 2012, 8:15:32 AM3/8/12
to rabbitmq...@lists.rabbitmq.com
I've finally gotten everything working inside my
project (Thanks, Alan!).

I'm trying a small test now where I have one producer
and one consumer on a queue. Running in Release mode
C++ (no debugging), I seem to top out around 3,700
messages/second.

Is that about what I should expect, or am I doing
something wrong? I thought it should be higher.

I can believe (but have not yet profiled it) that I'm
losing throughput because of all the std::strings and
shared_ptrs. If that's the case, I think that's just
the price I will have to pay for C++, unless I want
to drop down to using the underlying rabbitmq_c library.

Here's the guts of the producer:

using namespace AmqpClient;
Channel::ptr_t channel;
channel = Channel::Create();

channel->DeclareQueue("BasicReturnTestQueue", false, false, false, true);

const std::string constant ("foo");
try {
for (int i = 0; i < nmsgs; ++i) {
BasicMessage::ptr_t the_message = BasicMessage::Create(constant);
channel->BasicPublish("", "BasicReturnTestQueue", the_message, true,
false);
}
BasicMessage::ptr_t the_message = BasicMessage::Create("quit");
channel->BasicPublish("", "BasicReturnTestQueue", the_message, true,
false);
}
catch (MessageReturnedException& e) {
std::cout << "Message got returned: " << e.what();
std::cout << "\nMessage body: " << e.message()->Body();
}


And here's the consumer:

using namespace AmqpClient;
Channel::ptr_t channel;
channel = Channel::Create();

channel->DeclareQueue("BasicReturnTestQueue", false, false, false, true);
channel->BasicConsume("BasicReturnTestQueue", "consumer_tag1", true,
true, true, 10);


try {
while (1) {
Envelope::ptr_t env;
if (channel->BasicConsumeMessage("consumer_tag1", env, 0)) {
std::string msg = env->Message ()->Body ();
if (msg == "quit") {
return;
}
}
}
}
catch (MessageReturnedException& e)
{
std::cout << "Message got returned: " << e.what();
std::cout << "\nMessage body: " << e.message()->Body();
}

_______________________________________________
rabbitmq-discuss mailing list
rabbitmq...@lists.rabbitmq.com
https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss

Alan Antonuk

unread,
Mar 8, 2012, 12:16:02 PM3/8/12
to Eric J. Holtman, rabbitmq...@lists.rabbitmq.com
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

Having done some minimal performance testing what is slow is the way I do the BasicPublish.

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.

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:

#define BOOST_ALL_NO_LIB

#include <SimpleAmqpClient/SimpleAmqpClient.h>

#include <iostream>
#include <boost/timer/timer.hpp>
#include <stdlib.h>

using namespace AmqpClient;
int main()
{
    char* szBroker = getenv("AMQP_BROKER");
    Channel::ptr_t channel;
    if (szBroker != NULL)
        channel = Channel::Create(szBroker);
    else
        channel = Channel::Create();

channel->DeclareQueue("alanqueue");
channel->BindQueue("alanqueue", "amq.direct", "alankey");

BasicMessage::ptr_t msg_in = BasicMessage::Create();

msg_in->Body("This is a small message.");

  std::cerr << "Sending messages....";
  {
    boost::timer::auto_cpu_timer t;
    for (int i = 0; i < 100000; ++i)
    {
      channel->BasicPublish("amq.direct", "alankey", msg_in);
    }
  }
  std::cerr << "done.\n";

  std::cerr << "Receiving messages....";
std::string consumer = channel->BasicConsume("alanqueue", "consumertag");
  {
    boost::timer::auto_cpu_timer t;
    for (int i = 0; i < 100000; ++i)
    {
      channel->BasicConsumeMessage(consumer);
    }
  }
  std::cerr << "done.\n";
}


Output from this program:

Sending messages.... 24.938781s wall, 0.546003s user + 5.272834s system = 5.818837s CPU (23.3%)
done.
Receiving messages.... 0.165081s wall, 0.078001s user + 0.078001s system = 0.156001s CPU (94.5%)
done.

-Alan
Reply all
Reply to author
Forward
0 new messages