2015-07-06 2 views
2

Я пытаюсь получить мое приложение MEAN для производства. Приложение было построено на шаблоне Mean.js. По моему мнению, MEAN.js использует Forever.js для перезапуска приложения после ошибки (хотя документация по подготовке Mean.js для производства сильно отсутствует); однако представляется, что предлагаемый способ справиться с сбоем приложения - это использование доменов Node в сочетании с кластерами. Вот несколько ссылок:Использование доменов домена в Mean.js

  • Это с веб-страницы узла на осуждаетсяuncaughtException Событие:

Обратите внимание, что uncaughtException является очень грубый механизм для обработки исключений.

Не используйте его, вместо этого используйте домены.

Хотя я нашел много предложения по использованию доменов, я еще не нашел тот, который говорит мне, что нужно сделать для включения доменов в приложение, особенно тот, который уже был разработан.

Вопросы,

  • Что мне нужно сделать, чтобы интегрировать узел домены в приложение Mean.js? Из того, что я собрал (от Node.js доменов веб-страницы и here), вы бы в server.js в корне проекта Mean.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()?

ответ

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. 
};