简体   繁体   English

用于Express路由的NodeJS的RabbitMQ

[英]RabbitMQ for NodeJS with Express routing

My server is running NodeJS and uses the amqplib api to request data from another application. 我的服务器正在运行NodeJS,并使用amqplib api从另一个应用程序请求数据。 The NodeJS server is receiving the information successfully but there's a noticable delay and I'm trying to determine whether I am doing this in the most efficient manner. NodeJS服务器已成功接收到该信息,但存在明显的延迟,我正在尝试确定是否以最有效的方式进行此操作。 Specifically I'm concerned with the way that I open and close connections. 我特别关心的是打开和关闭连接的方式。
Project Layout 项目布局
I have two controller files that handle receiving and requesting the data, request.img.server.controller.js and receive.img.server.controller.js. 我有两个用于处理数据接收和请求的控制器文件request.img.server.controller.js和receive.img.server.controller.js。 Finally the routes handle the controller methods when a button on the front end is pushed, oct.server.routes.js. 最后,当按下前端的按钮oct.server.routes.js时,路由将处理控制器方法。

request.img.server.controller.js request.img.server.controller.js

'use strict';

var amqp = require('amqplib/callback_api');
var connReady = false;
var conn, ch;
amqp.connect('amqp://localhost:5672', function(err, connection) {
    conn = connection;
    connReady = true;
    conn.createChannel(function(err, channel) {
        ch = channel;
    });
});


exports.sendRequest = function(message) {
    console.log('sending request');

    if(connReady) {
        var ex = '';
        var key = 'utils';

        ch.publish(ex, key, new Buffer(message));
        console.log(" [x] Sent %s: '%s'", key, message);
    }
};

receive.img.server.controller.js receive.img.server.controller.js

var amqp = require('amqplib/callback_api');
var fs = require('fs');
var wstream = fs.createWriteStream('C:\\Users\\yako\\desktop\\binarytest.txt');

var image, rows, cols;
exports.getResponse = function(resCallback) {
    amqp.connect('amqp://localhost:5672', function(err, conn) {
        conn.createChannel(function(err, ch) {
            var ex = '';

            ch.assertQueue('server', {}, function(err, q) {
                console.log('waiting for images');
                var d = new Date();
                var n = d.getTime();
                ch.consume(q.queue, function(msg) {
                    console.log(" [x] %s: '%s'", msg.fields.routingKey, msg.content.toJSON());
                    rows = msg.content.readInt16LE(0);
                    cols = msg.content.readInt16LE(2);
                    console.log("rows = %s", msg.content.readInt16LE(0));
                    console.log("cols = %s", msg.content.readInt16LE(2));
                    image = msg.content;
                    var currMax = 0;
                    for (var i = 4; i < image.length; i+=2) {
                        if (image.readInt16LE(i) > currMax) {
                            currMax = image.readInt16LE(i);
                        }
                        wstream.write(image.readInt16LE(i) + ',');
                    }
                    console.log('done writing max is', currMax);
                    //console.log(image);
                    resCallback(rows, cols, image);
                }, {
                    noAck: true
                });
            });
        });
    });
};

oct.server.routes.js oct.server.routes.js

'use strict';

module.exports = function(app) {
    var request_img = require('../../app/controllers/image-tools/request.img.server.controller.js');
    var receive_img = require('../../app/controllers/image-tools/receive.img.server.controller.js');

    // oct routes
    app.get('/load_slice', function(req, res) {
        console.log('load slice hit');
        receive_img.getResponse(function (rows, cols, image) {
            res.end(image);
        });
        request_img.sendRequest('123:C:\\Users\\yako\\Documents\\Developer\\medicaldiag\\test_files\\RUS-01-035-09M-21.oct');
    });
};

The way you're opening connections is bad, and is at least part of the performance problem. 打开连接的方式不好,并且至少是性能问题的一部分。

Connections are expensive to open. 打开连接非常昂贵。 They open a new TCP/IP connection on a TCP/IP port between the client and rabbitmq server. 他们在客户端和Rabbitmq服务器之间的TCP / IP端口上打开新的TCP / IP连接。 This takes time, and uses up a limited resource on both the client and server. 这需要时间,并且会在客户端和服务器上消耗有限的资源。

Because of this, a single connection to RabbitMQ should be created and used within each of your node.js processes. 因此,应该在每个node.js进程中创建和使用与RabbitMQ的单个连接。 This one connection should be shared by all of the code in that process. 该连接应由该过程中的所有代码共享。

Whenever you need to do something with RabbitMQ, open a new channel on the shared connection and do your work. 每当您需要对RabbitMQ进行操作时,请在共享连接上打开一个新通道并进行工作。 Channels are cheap and are meant to be opened and closed as needed, within a connection. 通道很便宜,可以根据需要在连接内打开和关闭通道。

More specifically in your code, the receive.img.server.controller.js file is the major problem. 更具体地说,在您的代码中, receive.img.server.controller.js文件是主要问题。 This opens a new connection to RabbitMQ every time you call the getResponse method. 每次您调用getResponse方法时,都会打开一个与RabbitMQ的新连接。

If you have 10 users hitting the site, you'll have 10 open RabbitMQ connections when 1 would be sufficient. 如果您有10位用户访问该网站,那么当1个就足够时,您将拥有10个打开的RabbitMQ连接。 If you have thousands of users hitting the site, you'll have thousands of open RabbitMQ connections when 1 would be sufficient. 如果您有成千上万的用户访问该网站,那么当1足够时,您将具有成千上万的打开RabbitMQ连接。 You also run the risk of exhausting your available TCP/IP connections on the RabbitMQ server or client. 您还冒着用尽RabbitMQ服务器或客户端上可用的TCP / IP连接的风险。

Your receive.img.server.controller.js should look more like your request.img.server.controller.js - one connection open, and re-used all the time. 您的receive.img.server.controller.js应该看起来更像您的request.img.server.controller.js-一个连接打开,并且一直在重复使用。


Also, FWIW - I recommend using the wascally library for RabbitMQ w/ node.js. 另外, FWIW-我建议对wasMally库使用带有node.js的RabbitMQ。 This library sits on top of amqplib, but makes things significantly easier. 该库位于amqplib的顶部,但是使事情变得更加容易。 It will manage your one connection for you, and make it easier for you to send and receive messages. 它将为您管理一个连接,并使您更轻松地发送和接收消息。

I also have some training material available for RabbitMQ and node.js that covers the basics of amqplib and then moves in to using wascally for real application development. 我还提供了一些可用于RabbitMQ和node.js的培训材料,其中涵盖了amqplib的基础知识,然后着手使用wascally进行实际的应用程序开发。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM