如何在Heroku上与Node.js交streamWeb和Worker dynos?

Web Dynos可以处理HTTP请求

Web Dynos处理它们时, 工作者Dynos可以从中处理作业。

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

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

,把它发送给工人Dynos

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

,在网上展示结果。

这是可能的Node.js? (用RabbitMQ或Kue等)?

我在Heroku文档中找不到一个例子

还是应该在Web Dynos中实现所有代码,并只能扩展Web Dynos

作为关于后台作业和排队build议的高级文章,您的网页dynamic链接将需要通过中间机制(通常是一个队列)与您的工作人员dynos进行通信。

要完成听起来像你希望做的,遵循这个一般的方法:

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

就实际的实现而言,我并不太熟悉Node.js中最好的库,但是将这个过程粘合在一起的组件可以在Heroku上作为附加组件来使用 。

队列:AMQP是一个支持良好的队列协议, CloudAMQP插件可以作为Web和工作者dynos之间的消息队列。

共享状态:您可以使用其中一个Postgres加载项来共享正在处理的作业的状态或更高性能的内容(如Memcache或Redis) 。

所以,总结一下,你必须使用一个中间的附加组件在Heroku上的dynos之间进行通信。 虽然这种方法需要更多的工程,结果是一个适当的解耦和可扩展的架构。

据我所知,Heroku没有提供给你沟通的方式,所以你必须自己去build立。 为了与使用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;} }); 

我没有真正testing过这个,所以它可能需要一些工作和构build,但我认为基本的想法是清楚的。

编辑

只是注意到,你也用“redis”标记了这个标记,我想我应该补充一点,你也可以使用redis pub / sub在你的各个进程之间进行通信,如node_redis自述文件中所述 。