Nodejs RabbitMQ服务器上的高性能

时间:2016-12-28 09:03:52

标签: node.js rabbitmq node-amqp

我正在建立一个同时拥有一百万用户的分析系统。我使用RabbitMQ(如消息代理)来减少服务器的容量

这是我的图

enter image description here

我的系统包含3个组件。

发布商服务器:(制作人) 该系统建立在nodejs上。此系统的目的是将消息发布到queue

RabbitMQ队列:此系统存储了publisher server发送给的消息。之后,打开一个连接以从subscriber server的队列发送消息。

订阅服务器(消费者):此系统接收来自queue

的消息

发布者服务器源代码

var amqp = require('amqplib/callback_api');
amqp.connect("amqp://localhost", function(error, connect) {
    if (error) {
        return callback(-1, null);
    } else {
       connect.createChannel(function(error, channel) {
       if (error) {
           return callback(-3, null);
       } else {
         var q = 'logs';
         var msg = data; // object
         // convert msg object to buffer 
         var new_msg = Buffer.from(JSON.stringify(msg), 'binary');

        channel.assertExchange(q, 'fanout', { durable: false });
        channel.publish(q, 'message_queues', new Buffer(new_msg));
       console.log(" [x] Sent %s", new_msg);
        return callback(null, msg);
      }
    });
   }
}); 
  

专门与"message_queues"创建交换"fanout"以进行发送   向所有消费者广播

订阅者服务器源代码

var amqp = require('amqplib/callback_api');
amqp.connect("amqp://localhost", function(error, connect) {
    if (error) {
        console.log('111');
    } else {
        connect.createChannel(function(error, channel) {
            if (error) {
                console.log('1');
            } else {
                var ex = 'logs';

                channel.assertExchange(ex, 'fanout', { durable: false });
                channel.assertQueue('message_queues', { exclusive: true }, function(err, q) {
                    if (err) {
                        console.log('123');
                    } else {
                        console.log(" [*] Waiting for messages in %s. To exit press CTRL+C", q.queue);
                        channel.bindQueue(q.queue, ex, 'message_queues');

                        channel.consume(q.queue, function(msg) {
                            console.log(" [x] %s", msg.content.toString());

                        }, { noAck: true });

                    }
                });
            }
        });
    }

});
  

"message_queues"交换

收到消息

当我实施发送消息时。系统运行良好,但我尝试了该系统的基准测试性能(每秒约有1000个用户发送请求),那么系统存在一些问题。系统似乎是过载/缓冲区溢出(或某些东西不能正常工作)。

我只是在2天前读过关于rabbitmq的内容。我知道它的教程是基本的例子,所以我需要帮助在现实世界中构建系统而不是..任何 解决方案&建议

希望我的问题有意义

1 个答案:

答案 0 :(得分:2)

你的问题很笼统。您可能应提供更多详细信息,以帮助确定瓶颈并帮助您解决问题。 所以,首先我认为你应该检查兔子mq - 它是否是瓶颈。 有很多事情可能会出错:

  1. 可以使用该消息的消费者数量太少(我假设您使用了一组消费者)

  2. 网络太慢

  3. 队列和消息在Rabbit MQ的太多节点之间复制并且去做磁盘(可以像这样使用兔子mq)

  4. 消费者无法真正处理消息并且不断重新排队

  5. 所以,一般来说,在你的测试中你应该检查兔子mq,看看那里发生了什么。

    一旦到达队列的消息处于就绪状态,一旦发生这种情况,它将一直存在,直到连接到队列的一个消费者不会尝试接收消息进行处理

    当一个消费者(兔子在他们之间进行循环)选择要处理的消息时,状态将变为未确认 如果消费者无法处理该消息,它将被兔子重新排队,以便其他消费者有机会处理该消息。

    当然,如果消费者成功处理消息,则消息将从rabbit mq服务器消失。

    假设你已经安装了兔子mq web ui(我强烈推荐它特别适合初学者) - 你可以直观地看到队列中发生了什么 - 你会看到有多少消息处于就绪状态,有多少消息未被确认。 这有助于找出瓶颈。

    例如 - 如果您发现只有一条消息通常处于未确认状态,这可能意味着消费者无法处理该消息并将其发送回兔子。另一方面,新消息总是从生产者到达,因此 ready 消息的数量将非常快地增加 它还可以指出您只使用一个一次只能处理一条消息的消费者。所以你可以考虑在这里并行,通过在不同的线程中运行许多消费者甚至集群你的应用程序(兔子消费者可以驻留在不同的机器中)

    希望这对一般情况有帮助,当然,如前所述,如果您有更具体的问题 - 请提供有关测试期间究竟发生的事情的更多信息