2013-12-13 6 views
6

मेरे पास node.js. में एक एप्लिकेशन हैNode.js: क्लस्टर में differents कोड के साथ वर्कर?

यह आवेदन 3 भागों में बांटा गया है:

launcher.js है, जो दो अन्य भाग शुरू करते हैं, और सफाई से निपटने के बाद दुर्घटना/अपडेट करने पर उन्हें पुनः आरंभ करें।

app.js, जो कंप्यूटर पर स्वयं काम करते हैं।

server.js जिसका उपयोग लॉग और विभिन्न कमांड तक पहुंचने के लिए किया जाता है।

लांचर के लिए सरल कोड है:

var cluster = require('cluster'), 
    exec = require('child_process').exec, 
    server; 

if (cluster.isMaster) { 
    cluster.fork(); 
    server = exec('server.js'); 

    cluster.on('exit', function(worker, code, signal) { 
     //Clean corrupted data, log crash if neccessary, reload source code for update ... 
     cluster.fork(); 
    }); 
    server.on('exit', function() { 
     //Same as for app, with a different handling of signal... 
     server = exec('node server.js'); 
    }); 
} else { 
    var self = require('app.js); 
    self.start(); 
} 

क्लस्टर के साथ अच्छी बात यह है कि वे लांचर के समान प्रक्रिया में हो रहा है, तो मैं (बस बुला एप्लिकेशन को पुनः प्रारंभ करने के लिए बिना कुछ त्रुटि संभाल कर सकते हैं ऐप के अंदर एक सही "सॉफ्ट रीबूट" के लिए सही कार्य), और सब कुछ एक ही प्रक्रिया में रखें।

निष्पादन के साथ, मैं सर्वर को पुनरारंभ करने के साथ अटक गया हूं, कभी-कभी यह जानने के बिना कि क्या गलत हो गया है, और इसका मतलब यह है कि एक सबहेल है, जिसे मैं नापसंद करता हूं।

क्या क्लस्टर को फोर्क करने का कोई तरीका है, लेकिन एक अलग कोड शुरू करें?

उत्तर

2
var cluster = require('cluster'); 

if (cluster.isMaster) { 
    var app = cluster.fork(), 
     server = cluster.fork(); 

    app.on('message', function() { 
     app.send('app'); 
    }); 
    server.on('message', function() { 
     server.send('server'); 
    }); 
} else { 
    process.send(''); 
    process.on('message', function (code) { 
     var self=require('/path/to/' + code + '.js'); 
     self.start(); 
    }); 
} 

यह दो अलग क्लस्टर शुरू करने के लिए काम करते हैं, लेकिन मैं एप्लिकेशन को पुन: प्रारंभ पर अटक हूँ।


संपादित करें: फाइनल कोड, काम कर पुनः आरंभ करने के साथ:

var VERSION = 0.3, 
    util = require('util'), 
    cluster = require('cluster'), 
    PATH = process.argv[1].substr(0, process.argv[1].lastIndexOf('/') + 1), 
    lib = [], 
    childs = []; 

function listen(child, i) { 
    child.on('message', function(m) { 
     if (m.type === 'REBOOT') 
     { 
      reboot(); 
     } else if (m.type === 'CODE1') { 
      child.send({type: 'START', c: lib[i]}); 
     } else { 
      log('ERROR', ''); 
     } 
    }); 
    child.on('exit', function(worker, code, signal) { 
     delete require.cache[require.resolve(PATH + lib[i])]; 
     childs[i]=cluster.fork(); 
     listen(childs[i], i); 
    });   
} 

function reboot() { 
    i = 0; 
    do 
    { 
     childs[i].kill(); 
     i = i + 1; 
    }while (i < childs.length); 
} 

if (!cluster.isMaster) { 
    var self; 
    process.send({type:'START'}); 
    process.on('message', function(m) { 
     if (m.type === 'START'){ 
      self = require(PATH + m.c); 
      self.start(); 
     } 
    }); 
} else { 
    var i = 3; 

    if (process.argv.length < 4) 
    { 
     log('ERROR', 'Not enought argument'); 
     log('USAGE', 'node launcher.js x ...'); 
     log('USAGE', '...: Apps to start (at least one)'); 
     process.exit(-1); 
    } else {  
     do 
     { 
      lib.push(process.argv[i]); 
      i = i + 1; 
     }while (i < process.argv.length); 

     i = 0; 
     do 
     { 
       childs.push(cluster.fork()); 
       i = i + 1; 
     }while(i < lib.length); 

     i = 0; 
     do 
     { 
      listen(childs[i], i); 
      i = i + 1; 
     }while(i < lib.length); 
    } 
} 

आप अलग अलग फ़ाइलों में क्लस्टर के कोड की दुकान और तर्क के रूप में फाइल करने के लिए रास्तों के साथ इस कोड को शुरू करने की आवश्यकता होगी।

+0

आप 'की आवश्यकता होती है ('child_process') कार्यकारी क्यों शामिल किया,' पहले कोड उदाहरण में।? मैंने यह नहीं देखा कि आपने इसे कहीं भी इस्तेमाल किया है – qodeninja

+0

@qodeninja: उदाहरण को कम करने में त्रुटि जब यह बाद में कोड में उपयोग किया जाता है, लेकिन इसके लिए नहीं, धन्यवाद, यह आपको इंगित करने के लिए धन्यवाद:) – DrakaSAN

13

इस मेरे समाधान:

var cluster = require("cluster"); 
if(cluster.isMaster){ 
    // Forking Worker1 and Worker2 
    var worker1 = cluster.fork({WorkerName: "worker1"}); 
    var worker2 = cluster.fork({WorkerName: "worker2"}); 

    // Respawn if one of both exits 
    cluster.on("exit", function(worker, code, signal){ 
     if(worker==worker1) worker1 = cluster.fork({WorkerName: "worker1"});   
     if(worker==worker2) worker2 = cluster.fork({WorkerName: "worker2"}); 
    }); 
} else { 
    if(process.env.WorkerName=="worker1"){ 
     // Code of Worker1 
    } 

    if(process.env.WorkerName=="worker2"){ 
     // Code of Worker2 
    } 
} 

एक और अधिक गतिशील उदाहरण:

var cluster = require("cluster"); 

if(cluster.isMaster){ 

    // Forking Workers based on args  

    if(process.argv.length < 3){ 
     console.log("Usage: "+process.argv[1]+" module [module]"); 
    } 

    process.argv.forEach(function (val, index, array) { 
     // Don't use this script as worker (index 1 = self) 
     if(index>1){ 
     // Resolve the module before spawning to prevent loop. 
     try { require.resolve(val); spawn(val); } 
     catch(e) { console.error("Module '"+val+"' not found"); }  
     } 
    }); 

    cluster.on("exit", function(worker, code, signal){ 
     respawn(worker); 
    }); 
} else { 
    var self = require(process.env.WorkerScript); 
    self.start();  
} 


function spawn(script){ 
    cluster.fork({WorkerScript: script}).env = {WorkerScript: script}; 
} 

function respawn(worker){ 
    console.log("Respawning: "+worker.env.WorkerScript) 
    cluster.fork(worker.env).env = worker.env; 
} 
+0

अच्छा है, लेकिन कार्यकर्ता की संख्या हार्डकोडेड – DrakaSAN

+0

है इस उदाहरण श्रमिकों की संख्या हार्डकोडेड हैं। अधिक गतिशील उदाहरण के लिए मेरे संपादन पर एक नज़र डालें। गतिशील उदाहरण के लिए – Wolfspirit

+0

+1, यह मेरे अपने कोड से क्लीनर है। – DrakaSAN

संबंधित मुद्दे