我有一个基于SailsJs(http://sailsjs.org/)的应用程序,它必须处理一些CPU密集型任务。简而言之,我想使用cluster
(https://nodejs.org/api/cluster.html)模块将这些任务的处理委托给工作进程,以便不阻止Sails应用程序的主事件循环(因此可以响应正常请求。)
创建一个worker时,我收到EADDRINUSE
错误,因为Sails尝试再次运行并绑定到同一个端口。
示例代码:
// SomeSailsService.js
var cluster = require('cluster');
var Queue = require('bull');
var myQueue = Queue('myQueue', 'connection stuff', 'etc');
var numWorkers = 2;
var i;
if (cluster.isMaster) {
// Spawn some workers
for (i = 0; i < numWorkers; i++) {
cluster.fork();
}
} else {
// This is a worker, so bind to new job event
myQueue.process(function processJob(job, done) {
// CPU intensive shenanigans
});
}
module.exports = {
addToQueue: function(foo) {
myQueue.add({foo: foo});
}
};
运行上述操作时,Sails应用程序启动,然后启动时,两个工作程序尝试再启动应用程序两次。这导致以下两个错误:
events.js:72
throw er; // Unhandled 'error' event
^
Error: bind EADDRINUSE
at errnoException (net.js:904:11)
at net.js:1084:30
at Object.1:1 (cluster.js:594:5)
at handleResponse (cluster.js:171:41)
at respond (cluster.js:192:5)
at handleMessage (cluster.js:202:5)
at process.emit (events.js:117:20)
at handleMessage (child_process.js:322:10)
at child_process.js:396:7
at process.handleConversion.net.Native.got (child_process.js:91:7)
at process.<anonymous> (child_process.js:395:13)
at process.emit (events.js:117:20)
at handleMessage (child_process.js:322:10)
at Pipe.channel.onread (child_process.js:347:11)
有解决方法吗?或者解决这个问题的另一种方法是什么?
答案 0 :(得分:1)
我最终遵循this blog post的建议来启动应用的准系统实例。接下来,解决我的问题的基本过程是:
cluster.isMaster === true
。 上面的博客文章详细介绍了如何管理这些流程处理程序的创建和注册的详细信息(包括一个很好的实现)。它没有提及处理cluster
,但希望上述步骤可以帮助其他遇到此问题的人。
修改强>
根据Travis的建议(见下面的评论),我放弃了使用cluster
模块,而是创建了一个worker.js
文件,它做了很多相同的事情。即在worker.js
我启动了一个准系统Sails应用程序开始侦听新的工作。我的主要Sails应用程序(Web API)只是响应添加和获取作业(低延迟的东西)。
运行良好,应该可以轻松使用Heroku等服务。