我正在努力让我的MEAN应用程序准备好进行生产。该应用程序构建在Mean.js样板上。根据我的理解,MEAN.js在发生错误后使用Forever.js重新启动应用程序(虽然严格缺乏准备用于生产的Mean.js的文档);但是,似乎处理应用程序崩溃的建议方法是将Node&域与群集结合使用。以下是一些参考文献:
uncaughtException
活动的节点网页:请注意,uncaughtException是一种非常粗略的异常处理机制。
不要使用它,而是使用域名。
虽然我已经找到了许多使用域名的建议,但我还没有找到一个告诉我在应用程序中合并域名需要做些什么,特别是已经开发过的域名。
问题
将节点域集成到Mean.js应用程序需要做什么?根据我收集的内容(来自Node.js域名网页和here),您将进入Mean.js项目根目录中的server.js
并执行与此类似的操作:
var cluster = require('cluster');
var PORT = +process.env.PORT || 1337;
if (cluster.isMaster) {
//Fork the master as many times as required.
cluster.fork();
cluster.fork();
cluster.on('disconnect', function(worker) {
console.error('disconnect!');
cluster.fork();
});
} else {
var domain = require('domain');
var d = domain.create();
d.on('error', function(er) {
console.error('error', er.stack);
try {
// make sure we close down within 30 seconds
var killtimer = setTimeout(function() {
process.exit(1);
}, 30000);
// But don't keep the process open just for that!
killtimer.unref();
// stop taking new requests.
server.close();
// Let the master know we're dead. This will trigger a
// 'disconnect' in the cluster master, and then it will fork
// a new worker.
cluster.worker.disconnect();
// try to send an error to the request that triggered the problem
res.statusCode = 500;
res.setHeader('content-type', 'text/plain');
res.end('Oops, there was a problem!\n');
} catch (er2) {
// oh well, not much we can do at this point.
console.error('Error sending 500!', er2.stack);
}
});
d.run(function() {
//Place the current contents of server.js here.
});
}
我是否需要在domain.run()
中包装所有后端控制器?
答案 0 :(得分:1)
这个答案是通过实验和更多的挖掘找到的。我必须同时修改server.js
和config/express.js
才能使用域名。该域是每个请求的Express中间件的一部分。 不要在问题中使用代码,它不会按原样运行。
首先,我对server.js
所做的更改:
var init = require('./config/init')(),
config = require('./config/config'),
mongoose = require('mongoose'),
cluster = require('cluster');
var processes = 4; //Number of processes to run at the same time.
if(cluster.isMaster) {
for(var i = 0; i < processes; i++) {
cluster.fork();
}
cluster.on('disconnect', function(worker) {
console.error("Disconnect!");
cluster.fork();
});
} else {
/**
* Main application entry file.
* Please note that the order of loading is important.
*/
// Bootstrap db connection
var db = mongoose.connect(config.db, function(err) {
if (err) {
console.error('\x1b[31m', 'Could not connect to MongoDB!');
console.log(err);
}
});
// Init the express application
var expressConfig = require('./config/express');
var app = expressConfig.initialize(db);
app.use(function(err, req, res, next) {
console.error(err);
res.send(401).json({your_message_buddy: "Nice try, idiot."});
});
// Bootstrap passport config
require('./config/passport')();
// Start the app by listening on <port>
expressConfig.setServer(app.listen(config.port));
// Expose app
exports = module.exports = app;
// Logging initialization
console.log('MEAN.JS application started on port ' + config.port);
}
config/express.js
的必要更改:
var domain = require('domain'),
cluster = require('cluster');
var appServer = null;
module.exports = {};
/**
* Since we begin listening for requests in server.js, we need a way to
* access the server returned from app.listen() if we want to close the
* server after an error. To accomplish this, I added this function to
* pass the server object after we begin listening.
*/
module.exports.setServer = function(server) {
appServer = server;
};
module.exports.initialize = function(db) {
//Initialize express app
var app = express();
//Globbing model files
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
require(path.resolve(modelPath));
});
//Set up domain for request BEFORE setting up any other middleware.
app.use(function(req, res, next) {
//Create domain for this request
var reqdomain = domain.create();
reqdomain.on('error', function(err) {
console.error('Error: ', err.stack);
try {
//Shut down the process within 30 seconds to avoid errors.
var killtimer = setTimeout(function() {
console.error("Failsafe shutdown.");
process.exit(1);
}, 30000);
//No need to let the process live just for the timer.
killtimer.unref();
//No more requests should be allowed for this process.
appServer.close();
//Tell master we have died so he can get another worker started.
if(cluster.worker) {
cluster.worker.disconnect();
}
//Send an error to the request that caused this failure.
res.statusCode = 500;
res.setHeader('Content-Type', 'text/plain');
res.end('Oops, there was a problem. How embarrassing.');
} catch(err2) {
//Well, something is pretty screwed up. Not much we can do now.
console.error('Error sending 500!\nError2: ', err2.stack);
}
});
//Add request and response objects to domain.
reqdomain.add(req);
reqdomain.add(res);
//Execute the rest of the request chain in the domain.
reqdomain.run(next);
});
//The rest of this function, which used to be module.exports, is the same.
};