37

Web Dynos可以处理 HTTP 请求

而当Web Dynos处理它们时, Worker Dynos可以从中处理工作。

但我不知道如何让Web DynosWorker Dynos相互通信。

例如,我想接收Web Dynos的 HTTP 请求

, 发送给Worker Dynos

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

,在 Web 上显示结果。

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

我在Heroku 文档中找不到示例

还是我应该在Web Dynos中实现所有代码并仅扩展Web Dynos

4

2 回答 2

41

正如有关后台作业和排队的高级文章所建议的那样,您的网络测功机将需要通过中间机制(通常是队列)与您的工作人员测功机进行通信。

为了完成听起来你希望做的事情,请遵循以下一般方法:

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

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

队列:AMQP 是一个得到很好支持的队列协议,CloudAMQP插件可以作为你的 web 和 worker dynos 之间的消息队列。

共享状态:您可以使用Postgres插件之一来共享正在处理的作业的状态或性能更高的东西,例如MemcacheRedis

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

于 2012-07-11T17:43:50.750 回答
-4

据我所知,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 自述文件中所述。

于 2012-07-11T10:33:02.677 回答