2013-07-25 7 views
5

मैं पहली बार के लिए Node.js उपयोग कर रहा हूँ और एक सलाह के लिए उम्मीद:node.js + socket.io + redis आर्किटेक्चर - क्षैतिज सर्वर स्केलिंग सॉकेट कनेक्शन?

  • Node.js v0.11.3-पूर्व
  • एक्सप्रेस: ​​

    मैं अपने सर्वर पर निम्न प्रोग्राम स्थापित v3.3.4

  • socket.io v0.9.14
  • कनेक्ट-redis v1.4.5
  • Redis सर्वर वी = 2.6.14
  • redis -cli 2.6.14 सबसे

सबसे पहले, मैं एक एक्सप्रेस एप्लिकेशन बनाया:

express testApplication 

"package.json" बनाया में मैं सभी आवश्यक depencies परिभाषित किया।

शुरू से ही मैं खड़ी "cluster.js" नामक एक फ़ाइल में स्केलिंग (बहु प्रक्रियाओं) के लिए एक क्लस्टर में परिभाषित किया गया:

var cluster = require('cluster'); 

if(cluster.isMaster) { 
     var noOfWorkers = process.env.NODE_WORKERS || require('os').cpus().length; 

     console.log("Workers found: " + noOfWorkers); 

     for (var i = 0; i < noOfWorkers; i += 1) { 
       cluster.fork(); 
     } 
} else { 
     require('./app.js'); 
} 

cluster.on('exit', function(worker, code, signal) { 
     var exitCode = worker.process.exitCode; 

     console.log('worker' + worker.process.pid + ' died (' + exitCode + '). restarting...'); 

     if(typeof cluster.workers[worker.id] != "undefined") 
       cluster.workers[worker.id].delete(); 

     cluster.fork(); 
}); 

मेरी "app.js" फ़ाइल में मैं सॉकेट के लिए REDIS परिभाषित किया। आईओ भंडारण:

io.set('store', new RedisStore({ 
      redisPub: pub, 
      redisSub: sub, 
      redisClient: client 
      })); 

अभी तक, बहुत अच्छा, यह सब बहुत अच्छा काम करता है।

जब कोई ग्राहक सॉकेट.io सर्वर से कनेक्ट होता है, तो क्लस्टर विभिन्न श्रमिकों के साथ कनेक्शन को संभालता है।

मेरा इरादा यह है कि क्लाइंट किसी विशिष्ट क्लाइंट को एक संदेश भेज सकता है, इसलिए socket.io सर्वर को केवल इस उपयोगकर्ता को संदेश भेजने के लिए प्राप्ति से सॉकेट ढूंढना होगा। मेरे लिए समाधान यह है कि, मैं एक सरणी में प्रत्येक उपयोगकर्ता के लिए सभी बनाई गई सॉकेट आईडी को संग्रहीत करता हूं और संदेश भेजते समय, मैं सरणी में प्रासंगिक सॉकेट आईडी का चयन करता हूं, आईडी द्वारा सॉकेट प्राप्त करता है, और सॉकेट को संदेश भेजता है)।

यह सॉकेट.io एप्लिकेशन के लिए बहुत बढ़िया काम करता है, जो केवल एक सर्वर पर चल रहा है। अब, मैं एक ही प्रोग्राम को एक ही प्रोग्राम, मॉड्यूल और पैकेज के साथ कॉन्फ़िगर करना चाहता हूं। भार संतुलन शायद हैपरॉक्स द्वारा संभाला जाएगा। तो socket.io कनेक्शन (सॉकेट) सर्वर ए और सर्वर बी पर संग्रहीत और प्रबंधित किया जाएगा।

उदाहरण परिदृश्य:

उपयोगकर्ता Aसर्वर एक और उपयोगकर्ता Bसर्वर बी को जोड़ता को जोड़ता है। इसका मतलब है, कि उपयोगकर्ता एक सर्वर पर सर्वर बी पर एक अंड उपयोगकर्ता B एक सॉकेट है

कैसे यह संभव है कि आवेदन जानता है, यह सर्वर बी पर उपयोगकर्ता B के सॉकेट देखने के लिए भेजने के लिए किया है संदेश? सर्वर ए पर यह सॉकेट नहीं मिलेगा, क्योंकि यह सर्वर बी पर बनाया गया था।

Thx एक बहुत!

उत्तर

5

जब आप क्षैतिज स्केलिंग रहे हैं, तो आप अपने सर्वर के बीच एक डेटासंग्रह साझा करने के लिए की जरूरत है। सुविधाजनक रूप से, आपके पास पहले से ही एक आदर्श है, जो रेडिस है। एक सरणी में अपने सॉकेट मैपिंग को रखने के बजाय, आपको इसे रेडिस में धक्का देना होगा, और वहां से लुकअप करना होगा।

उसके बाद, आप सर्वर को एक दूसरे को संदेश भेजने के लिए तय कर सकते हैं या तो, या, अधिक scalably, साथ ही Redis के माध्यम से संदेश भेजते हैं। इसलिए, प्रत्येक सर्वर रेडिस पर इसकी कतार को देखेगा यह देखने के लिए कि कौन से संदेश इसे सॉकेट पर भेजना चाहिए। जब किसी सर्वर को कोई संदेश प्राप्त होता है, तो वह इसे सर्वर पर संबोधित रेडिस में डाल देगा जो इसे वितरित करना चाहिए। यदि संदेशों का ऑर्डर आपके लिए मायने रखता है, तो मैं रेडिस के शीर्ष पर https://github.com/learnboost/kue को परत के रूप में देखने की अनुशंसा करता हूं।

+0

@elchueko क्या आप एक उदाहरण पोस्ट कर सकते हैं कि आपने इसे रेडिस के साथ कैसे हल किया? – patrick

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