Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Heroku上的节点JS消息队列_Node.js_Heroku_Rabbitmq_Backgroundworker_Message Queue - Fatal编程技术网

Node.js Heroku上的节点JS消息队列

Node.js Heroku上的节点JS消息队列,node.js,heroku,rabbitmq,backgroundworker,message-queue,Node.js,Heroku,Rabbitmq,Backgroundworker,Message Queue,我需要将在Heroku上运行的节点JS服务器移动到消息队列体系结构。目前,服务器接收HTTP请求,进行一些处理,并做出响应。问题是处理需要一些时间,特别是当有大量请求时。这种漫长的处理时间会导致服务器超时、过载和崩溃!我的阅读告诉我需要一个背景工人来处理 我对消息队列和后台工作人员没有任何经验,我正在寻找一个非常简单的示例开始。有人能推荐一个简单易懂的模块或示例来开始吗 我找到了一些,但它们很复杂,我迷路了!我想要一个赤裸裸的例子,我可以建立 我在这里找到了一个非常简单的示例(后面是更深入的示例

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

我对消息队列和后台工作人员没有任何经验,我正在寻找一个非常简单的示例开始。有人能推荐一个简单易懂的模块或示例来开始吗


我找到了一些,但它们很复杂,我迷路了!我想要一个赤裸裸的例子,我可以建立

我在这里找到了一个非常简单的示例(后面是更深入的示例):

让我们看看如何使用RabbitMQ实现这一点。 首先,您需要在开发环境中使用RabbitMQ服务器。 如果您还没有(检查“sudo服务rabbitmq服务器状态”),您可以按如下方式安装(在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。 我假设当前您的proc文件中只有一个Web dyno。 因此,您需要添加另一行来实例化worker,例如:

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”进行测试。您应该看到,您的应用程序中现在运行着两个进程,“Web”和“worker”。无论何时在Web dyno中调用publishMsg(),您都应该希望看到wroker dyno将消息内容吐出到您的控制台。要查看RabbitMQ队列中发生的情况,可以使用:

sudo rabbitmqctl list_queues

酷。你有我能看到的任何电影预览/样本吗?我想看看这是否是正确的级别。你教的东西适用于Heroku吗?这里有一个采访是免费的:但我没有太多的预览,否则。。。我应该准备一个预览视频谢谢你的解释,这是非常有帮助的。不过我有一个问题。。如何在不同模块之间共享此publisherChnl?我假设您的意思是希望能够从web应用程序中的多个node.js模块在队列上发布消息?如果是这样,只需将函数publishMsg导出为“exports.publishMsg=publishMsg”,这样您就可以在任何地方调用它。如果这不是你的意思,那么请澄清。是的,这是我的问题。谢谢你的澄清。我还有一个疑问。。我尝试了这段代码,看起来startConsuming()是在createConsumerChannel()完成之前运行的。最好的连锁方式是什么?我可以在一个
consumerChnl=ch之后调用startConsuming()但这是正确的方法吗?