如何在Heroku上与Node.js交streamWeb和Worker dynos?
Web Dynos可以处理HTTP请求
当Web Dynos处理它们时, 工作者Dynos可以从中处理作业。
但是我不知道如何让Web Dynos和Worker 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自述文件中所述 。