Express を使用してノード内のドメインとクラスターをいじっていて、この状況に陥りました。コアごとにワーカーを生成するクラスターがあり、ワーカーごとに、リクエストごとのドメイン戦略を使用してエラーを処理するエクスプレスサーバーを作成します。
以下に示す解決策はそのままでは正常に機能しますが、ドメインにリクエスト オブジェクトとレスポンス オブジェクトを明示的に追加すると、エラー ミドルウェアの呼び出しが停止します。この動作が導入される理由がわかりません。
質問:
- なぜ起こっているのですか?
- ドメインを正しい方法で使用していますか?
- 「process.domain」を介してワーカーの現在のドメインにアクセスできますか、それとも別のことをする必要がありますか?
前もって感謝します!
私のapp.js:
var express = require('express')
, http = require('http')
, path = require('path')
, domain = require('domain')
, cluster = require('cluster')
, http = require('http')
, numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// fork workers
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
// when a worker dies create a new one
cluster.on('exit', function(worker, code, signal) {
cluster.fork();
});
} else {
var app = express();
//domains
app.use(function domainMiddleware(req, res, next) {
var reqDomain = domain.create();
res.on('close', function () {
reqDomain.dispose();
});
res.on('finish', function () {
reqDomain.dispose();
});
reqDomain.on('error', function (err) {
reqDomain.dispose();
// delegate to express error-middleware
next(err);
});
// Adding the request and response objects to the domain
// makes the express error-middleware to not being called.
// reqDomain.add(req);
// reqDomain.add(res);
reqDomain.run(next);
});
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
//app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// for testing which cluster that serves the request
app.get('/', function(req, res, next) {
res.json(200, { id: cluster.worker.id });
});
app.get('/error', function(req, res, next) {
var fs = require('fs');
// intentionally force an error
fs.readFile('', process.domain.intercept(function(data) {
// when using intercept we dont need this line anymore
//if (err) throw err;
res.send(data);
}));
});
app.use(function(err, req, res, next) {
console.log('ERROR MIDDLEWARE', err);
res.writeHeader(500, {'Content-Type' : "text/html"});
res.write("<h1>" + err.name + "</h1>");
res.end("<p>" + err.message + "</p>");
});
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
}