2014-09-30 13 views
6

क्या किसी को भी एकाधिक कोर पर node.js - socket.io आधारित ऐप को स्केल करने के लिए एक अच्छा समाधान पता है? मैं वर्तमान में socket.io प्रलेखन में प्रस्तुत किए गए समाधान का परीक्षण कर रहा हूं, कई नोड्स पर socket.io का उपयोग करने के लिए, लेकिन एक ठोस सफलता के बिना।स्केल नोड.जेएस [email protected]*.* क्लस्टर और सॉकेट.ओ-रेडिस के साथ हेरोकू

मैंने गिटूब पर इसके लिए एक खेल का मैदान बनाया है: https://github.com/liviuignat/socket.io-clusters जो सॉकेट.ओ साइट से चैट एप्लिकेशन की एक बिट संशोधित प्रति है। यह express, cluster, [email protected] और socket.io-redis का उपयोग करता है।

वर्तमान में शाखा feature/sticky में sticky-session का उपयोग करके एक कार्यान्वयन भी है जो बेहतर काम करता प्रतीत होता है।

अंत में आवेदन को पर प्रकाशित किया जाना चाहिए Heroku, एकाधिक डायनोस पर स्केल किया गया।

शुरू में मैं कुछ इस तरह कर रही tryied - केवल क्लस्टर नोड्स के लिए सर्वर शुरू करने के लिए, लेकिन मैं हमेशा त्रुटि मिलती है: में विफल रहा है: कनेक्शन एक हाथ मिलाना प्रतिक्रिया प्राप्त करने से पहले बंद कर दिया

if (cluster.isMaster) {  
    for (var i = 0; i < numCPUs; i++) { 
    cluster.fork(); 
    } 

    cluster.on('exit', function(worker, code, signal) { 
    console.log('worker ' + worker.process.pid + ' died'); 
    }); 
} else { 
    var server = new Server({ 
     dirName: __dirname, 
     enableSocket: true 
    }) 
    .setupApp() 
    .setupRoutes() 
    .start(); 
} 

तो मैं करने की कोशिश की मास्टर नोड्स के लिए भी सर्वर शुरू कर:

if (cluster.isMaster) { 
    var server = new Server({ 
     dirName: __dirname, 
     enableSocket: true 
    }) 
    .setupApp() 
    .setupRoutes() 
    .start(); 

    for (var i = 0; i < numCPUs; i++) { 
    cluster.fork(); 
    } 

    cluster.on('exit', function(worker, code, signal) { 
    console.log('worker ' + worker.process.pid + ' died'); 
    }); 
} else { 
    var server = new Server({ 
     dirName: __dirname, 
     enableSocket: true 
    }) 
    .setupApp() 
    .setupRoutes() 
    .start(); 
} 

मैं भी शाखा feature/sticky, जो लगता है दोनों में sticky-session और socket.io-redis का उपयोग कर इसे करने की कोशिश सफलता के साथ प्रदर्शन करते हैं, लेकिन अभी भी एक अच्छा समाधान हो रहा है नहीं करता है:

if (cluster.isMaster) { 
    sticky(function() { 
    var server = new Server({ 
     dirName: __dirname, 
     enableSocket: true 
     }) 
     .setupApp() 
     .setupRoutes(); 
    return server.http; 
    }).listen(3000, function() { 
    console.log('server started on 3000 port'); 
    }); 

    for (var i = 0; i < numCPUs; i++) { 
    cluster.fork(); 
    } 

    cluster.on('exit', function(worker, code, signal) { 
    console.log('worker ' + worker.process.pid + ' died'); 
    }); 
} else { 
    sticky(function() { 
    var server = new Server({ 
     dirName: __dirname, 
     enableSocket: true 
     }) 
     .setupApp() 
     .setupRoutes(); 
    return server.http; 
    }).listen(3000, function() { 
    console.log('server started on 3000 port'); 
    }); 
} 

मैं अगले दिनों के लिए और अधिक परीक्षण करना होगा, लेकिन, यह एक बहुत मदद मिलेगी अगर किसी को कुछ विचारों के साथ आ सकता है।

धन्यवाद,

उत्तर

2

आप शायद socket.io-redis की तलाश में हैं। http://socket.io/blog/introducing-socket-io-1-0/

यहाँ ('अनुमापकता' के लिए स्क्रॉल) कैसे socket.io + एक्सप्रेस के साथ मचान बनाने के लिए पर एक छोटा उदाहरण है:

var cluster = require('cluster'); 

var express = require('express') 
    , app = express() 
    , server = require('http').createServer(app); 

var 
    io = require('socket.io').listen(server) 
    var redis = require('socket.io-redis'); 
    io.adapter(redis({ host: 'localhost', port: 6379 })); 



var workers = process.env.WORKERS || require('os').cpus().length; 

/** 
* Start cluster. 
*/ 

if (cluster.isMaster) { 

    /** 
    * Fork process. 
    */ 

    console.log('start cluster with %s workers', workers-1); 
    workers--; 
    for (var i = 0; i < workers; ++i) { 
    var worker = cluster.fork(); 
    console.log('worker %s started.', worker.process.pid); 
    } 

    /** 
    * Restart process. 
    */ 

    cluster.on('death', function(worker) { 
    console.log('worker %s died. restart...', worker.process.pid); 
    cluster.fork(); 
    }); 


} else { 
    server.listen(process.env.PORT || 9010); 
} 

Redis/उप पब भी है और सभी socket.io नोड्स की जरूरत है एक चैनल से सभी संदेश प्राप्त करने के लिए redis की सदस्यता लें। इस तरह एक प्रक्रिया एक चैनल (प्रकाशित) को एक संदेश प्रसारित कर सकती है और अन्य सभी प्रक्रियाओं को उनके कनेक्टेड क्लाइंट (सब्सक्राइब) में प्रसारित करने के लिए न्यूनतम विलंबता वाले संदेश प्राप्त होते हैं। आप इसे रेडिस आधारित सत्रों के साथ भी बढ़ा सकते हैं।

क्लस्टर मॉड्यूल जिसका आप उल्लेख कर रहे हैं मेरी राय में थोड़ा भ्रामक है। यह अवधारणा को समझने तक अदृश्य उप-प्रक्रियाओं को बनाने में मदद करता है, लेकिन कई नोड्स में चैनल को 'सिंक्रनाइज़ नहीं' करता है। यदि आपके ग्राहकों को दूसरों के साथ संवाद करने की आवश्यकता नहीं है तो यह ठीक है। यदि आप सभी नोड्स पर सभी कनेक्टेड क्लाइंट्स को संदेश प्रसारित करना चाहते हैं तो आपको रेडिस मॉड्यूल की आवश्यकता है।

+0

हाय स्टीफन, मैं सफलता के साथ सॉकेट.ओ-रेडिस का उपयोग कर रहा हूं। –

+0

मैंने एक उदाहरण जोड़ा है जो एक परियोजना से लिया गया है जिसे मैंने कुछ समय पहले काम किया था। उस समय चीजें थोड़ा अलग थीं, लेकिन मैंने इसे socket.io> = 1.0 – Steffen

+0

के लिए सॉकेट.ओ-रेडिस का उपयोग करने के लिए अपडेट किया है, ऐसा लगता है कि मैंने इसे एक साधारण सर्वर के साथ काम करने में कामयाब रहा है (देखें: https://github.com/liviuignat/chat-example-cluster/blob/master/index.js)।मैं इसके साथ थोड़ा और खेलूँगा, क्योंकि मेरे मुख्य प्रोजेक्ट में अभी भी समस्याएं हैं। –

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