如何在Heroku上与Node.js通信Web和Worker dynos?

时间:2012-07-11 09:39:10

标签: node.js heroku redis rabbitmq kue

Web Dynos 可以处理HTTP请求

Web Dynos 处理它们时工作人员Dynos 可以处理它的作业。

但我不知道如何让 Web Dynos 工作者Dynos 相互沟通。

例如,我想通过 Web Dynos

接收HTTP请求

,将其发送至工作人员Dynos

,处理作业并将结果发回 Web Dynos

,在网上显示结果。

这在Node.js中是否可行? (使用RabbitMQ或Kue等)?

我在Heroku Documentation

中找不到示例

或者我应该只在 Web Dynos 中实施所有代码并仅扩展 Web Dynos 吗?

2 个答案:

答案 0 :(得分:37)

正如background jobs and queuing上的高级文章所暗示的那样,您的网络动态需要通过中间机制(通常是队列)与您的工作人员dynos进行通信。

要完成听起来像你希望遵循这种一般方法的内容:

  • 网络dyno
  • 收到网络请求
  • Web dyno向队列添加作业
  • 工作人员dyno从队列中接收作业
  • 工作人员dyno执行作业,将增量进度写入共享组件
  • 浏览器端轮询请求来自Web dyno的作业状态
    • Web dyno查询共享组件以获取后台作业的进度并将状态发送回浏览器
  • 工作人员dyno完成作业的执行并在共享组件中将其标记为完成
  • 浏览器端轮询请求来自Web dyno的作业状态
    • Web dyno查询共享组件以获取后台作业的进度,并将完成状态发送回浏览器

就实际实现而言,我对Node.js中最好的库并不太熟悉,但将这个过程粘合在一起的组件在Heroku上可以add-ons获得。

队列:AMQP是一个受到良好支持的队列协议,CloudAMQP附加组件可以作为您的网络和工作人员dynos之间的消息队列。

共享状态:您可以使用其中一个Postgres加载项来共享正在处理的作业的状态或更高效的内容,例如MemcacheRedis

因此,总而言之,您必须使用中间附加组件在Heroku上的dynos之间进行通信。虽然这种方法涉及更多的工程,但结果是一个适当解耦和可扩展的架构。

答案 1 :(得分:-3)

据我所知,Heroku不提供与您沟通的方式,因此您必须自己构建。为了使用Node与另一个进程通信,您可能必须处理该进程。 stdin / out / err手动,类似这样:

var attachToProcess = function(pid) {
    return {
        stdin: fs.createWriteStream('/proc/' + pid + '/fd/0'),
        stdout: fs.createReadStream('/proc/' + pid + '/fd/1'),
        stderr: fs.createReadStream('/proc/' + pid + '/fd/2')
    };
};

var pid = fs.readFile('/path/to/worker.pid', 'utf8', function(err, pid) {
    if (err) {throw err;}
    var worker = attachToProcess(Number(pid));
    worker.stdin.write(...);
});

然后,在您的工作进程中,您必须将pid存储在该pid文件中:

fs.writeFile('/path/to/worker.pid', process.pid, function(err) {
    if (err) {throw err;}
});

我还没有真正测试过这些,所以它可能需要一些工作并在此基础上进行构建,但我认为基本的想法是明确的。

修改

只是注意到你用" redis"标记了这个标签。同时,我认为我应该补充一点,你也可以使用redis pub / sub在各个流程之间进行通信,如node_redis readme中所述。