繁体   English   中英

Heroku上的节点JS消息队列

[英]Node JS message queue on Heroku

我需要将在Heroku上运行的Node JS服务器移动到消息队列架构。 目前,服务器接收HTTP请求,进行一些处理并进行响应。 问题是处理需要一些时间,特别是当有大量请求时。 这个漫长的处理时间会导致服务器超时,过载和崩溃! 我的阅读告诉我需要后台工作人员来处理。

我对消息队列和后台工作者没有经验,我正在寻找一个非常简单的示例来开始。 任何人都可以建议一个简单,易懂的模块或示例来开始?

我发现了一些例子,但它们很复杂,我迷路了! 我想要一个我可以构建的准系统示例。

让我们看看如何使用RabbitMQ做到这一点。 首先,您需要一个RabbitMQ服务器才能在您的开发环境中使用。 如果你还没有它(检查“sudo service rabbitmq-server status”)你可以安装(在ubuntu或类似的)如下:

sudo su -c "echo 'deb http://www.rabbitmq.com/debian/ testing main' >> /etc/apt/sources.list"
wget http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
sudo apt-key add rabbitmq-signing-key-public.asc
sudo apt-get update
sudo apt-get install rabbitmq-server
rm  rabbitmq-signing-key-public.asc

然后,让服务器运行:

sudo service rabbitmq-server start

您还需要为Heroku部署配置RabbitMQ服务。 我们在这个例子中使用CloudAMPQ。 您可以将其免费计划添加到您的Heroku应用程序中:

heroku addons:create cloudamqp:lemur 

这将在您的Heroku应用程序中创建一个新的CLOUDAMQP_URL环境变量。

接下来,您将需要一个适合您的node.js应用程序的RabbitMQ客户端。 其中有一些,但对于这个例子,让我们使用ampqlib:

npm install ampqlib --save

这应该在package.json依赖项中添加类似以下行的内容:

"amqplib": "^0.4.1",

接下来就是在你的Heroku应用程序中添加一个背景“worker”dyno。 我假设你的Procfile中目前只有一个Web dyno。 因此,您需要添加另一行来实例化工作程序,例如:

worker: node myworker.js

最后,您需要编写代码,使您的Web dyno能够通过RabbitMQ与您的worker dyno进行交互。

为了这个例子,我假设您的Web dyno将“发布”消息到RabbitMQ消息队列,并且您的worker dyno将“消费”这些消息。

所以,让我们开始编写用于发布到消息队列的代码。 此代码需要在Web dyno中的某个位置运行:

// Define ampq_url to point to CLOUDAMPQ_URL on Heroku, or local RabbitMQ server in dev environment
var ampq_url = process.env.CLOUDAMQP_URL || "amqp://localhost";
var ampq_open = require('amqplib');
var publisherChnl;

function createPublisherChannel() {

    // Create an AMPQ "connection"
    ampq_open.connect(ampq_url)
        .then(function(conn) {
            // You need to create at least one AMPQ "channel" on your connection   
            var ok = conn.createChannel();
            ok = ok.then(function(ch){
                publisherChnl = ch;
                // Now create a queue for the actual messages to be sent to the worker dyno 
                publisherChnl.assertQueue('my-worker-q');
            })
        })
    }

function publishMsg() {
     // Send the worker a message
     publisherChnl.sendToQueue('my-worker-q', new Buffer('Hello world from Web dyno'));
}

在初始化Web dyno期间,您需要调用createPublisherChannel()。 然后,只要您想要将消息发送到队列,就调用publishMsg()。

最后,让我们编写用于在worker dyno中使用上述消息的代码。 因此,例如,在myworker.js中添加以下内容:

// Just like in Web dyno...
var amqp_url = process.env.CLOUDAMQP_URL || "amqp://localhost";
var open_ampq = require('amqplib').connect(amqp_url);
var consumerChnl;    

// Creates an AMPQ channel for consuming messages on 'my-worker-q'
function createConsumerChannel() {     
    open_ampq
        .then(function(conn) {
            conn.createChannel()
                .then(function(ch) {
                    ch.assertQueue('my-worker-q');
                    consumerChnl = ch;
            });
        });
}  

function startConsuming() {
    consumerChnl.consume('my-worker-q', function(msg){
        if (msg !== null) {
            console.log(msg.content.toString());
            // Tell RabbitMQ server we have consumed the message
            consumerChnl.ack(msg);
        }
    })
} 

createConsumerChnl().then(startConsuming); 

最后,用“heroku local”进行测试。 您应该会看到您现在在应用程序中运行了2个进程,“Web”和“worker”。 无论何时在Web dyno中调用publishMsg(),您都应该看到wroker dyno将消息内容吐出到您的控制台。 要查看RabbitMQ队列中发生的情况,您可以使用:

sudo rabbitmqctl list_queues

我在这里找到了一个非常简单的例子(后面是更深层的例子): https//www.rabbitmq.com/tutorials/tutorial-one-javascript.html

暂无
暂无

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

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