让我们看看如何使用 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”测功机。
我假设目前您的 Procfile 中只有一个 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”进行测试。您应该会看到您的应用程序中正在运行 2 个进程,“Web”和“worker”。每当您在 Web dyno 中调用 publishMsg() 时,您应该希望看到 wroker dyno 将消息内容吐出到您的控制台。要查看您的 RabbitMQ 队列中发生了什么,您可以使用:
sudo rabbitmqctl list_queues