محمدرضا عرفانی
5 سال پیش توسط محمدرضا عرفانی مطرح شد
7 پاسخ

کلاستر در نود جی اس

سلام
در صورت رفع مشکل حاضرم وجه ناقابلی به حسابش واریز کنم.
مدتیه که برنامه رو بر روی کلاستر ران می کنم.
متاسفانه سوکت ها بدرستی کار نمی کنه.
مشکل از اینجا شروع میشه که بعد از راه اندازی برنامه بر روی کلاستر، برنامه بر روی core های مختلف cpu اجرا میشه که مزیتش اینه که شما انگار چند تا سرور داری...
اما اشکالش اینه که مثلا کلاینت 1 میخواد پیامی رو به همه ی کسانی که به سرور متصل هستند، ارسال کند.
که در واقع این اتفاق نمی افته...جون بعضی ها به core1 وصل هستند.بعضی ها به core2 وصل هستند.و اونایی که به core1 وصل هستند از اونهایی که به core2 وصل هستند خبر ندارند.
اگر کسی با کلاستر و سوکت کار کرده، خواهش می کنم اعلام کند.
در صورت رفع مشکل حاضرم وجه ناقابلی به حسابش واریز کنم.


ثبت پرسش جدید
emadansari75
تخصص : senior node js developer
@emad.ansary 4 سال پیش آپدیت شد
0

سلام محمد جان، زمان زیادی گذشته ولی من پاسخ رو مینویسم تا اگر کسی مشکل مشابه داشته باشه بتونه به پاسخ برسه
متاسفانه این مشکل توی کلاستر وجود داره و اگر از worker thread های نود توی نسخه ی آخرش استفاده نمیکنی ، برای حل مشکت بهت redis socket io رو پیشنهاد میکنم ، درواقع سوکت هات یه share memory خواهند داشت داکیومنت های socket.io-redis میتونه بیشتر بهت کمک کنه (اینجا)
اگر بخوام توضیح بدم سوکت سرور رو به شکل معمول ران نمیکنی و از redis استفاده میکنی تا توی همه ی پراسس هات یکسان باشه، همونطور که میدونی cluster توی بهبود پرفرمنس درخواست های I/O توفیق چندانی نداره پس برای این قضیه هم نگرانی نداریم. پس اگر از adapter های redis توی هر پروسه استفاده کنیم مشکل حل میشه و کد یه چیزی شبیه کد زیر میشه :


var cluster = require('cluster');
var os = require('os');

if (cluster.isMaster) {
  // we create a HTTP server, but we do not use listen
  // that way, we have a socket.io server that doesn't accept connections
  var server = require('http').createServer();
  var io = require('socket.io').listen(server);
  var redis = require('socket.io-redis');

  io.adapter(redis({ host: 'localhost', port: 6379 }));

  setInterval(function() {
    // all workers will receive this in Redis, and emit
    io.emit('data', 'payload');
  }, 1000);

  for (var i = 0; i < os.cpus().length; i++) {
    cluster.fork();
  }

  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  }); 
}

if (cluster.isWorker) {
  var express = require('express');
  var app = express();

  var http = require('http');
  var server = http.createServer(app);
  var io = require('socket.io').listen(server);
  var redis = require('socket.io-redis');

  io.adapter(redis({ host: 'localhost', port: 6379 }));
  io.on('connection', function(socket) {
    socket.emit('data', 'connected to worker: ' + cluster.worker.id);
  });

  app.listen(80);
}```

دانیال
@dani999dani99 5 سال پیش آپدیت شد
1

سلام @rezaerfani
احتمالا از socket.io استفاده می کنی می تونی دو تا سرور رو از طریق سوکت به هم متصل کنی. یعنی یکی از سرور ها رو به عنوان سرور اصلی در نظر بگیری باقی سرور ها رو به عنوان کلاینت از طریق سوکت به هم متصل کنی .
باید socket.io-client رو فراخوانی کنی و بعد برنامه ای بنویسی که سرور دوم پیام سرور اول رو به سوکت های خودش بفرسته ، هم چنین هر کدوم از سرور های متصل پیام خودشون رو به سرور اصلی بفرستن تا سرور اصلی هم دوباره این پیام رو به سرور های متصل به خودش و احتمالا کاربرای متصل به خودش بفرسته . البته نمی دونم چرا این تصمیمو گرفتی که به این طریق سیستمت رو راه بندازی ولی به نظرم این جوری سرعتت پایین میاد :

// Server #2
const ioClient = require('socket.io-client')
const socket = ioClient.connect('localhost:8080')
socket.on('connect',function(socketC){
console.log('connected to server 1')
socketC.on('msgFromServer1',function(data){
// payam ersal beshe baray socket hay in server
}
}

در ضمن این رو هم بگم که اینجا کسی نباید بابت کمکی که می کنه پول درخواست کنه ! شما هم اگر میخواید که کار دوستان رو جبران کنید می تونید در فروم فعالیت کنید و مشکل باقی دوستان رو تا حد توان رفع کنید.


محمدرضا عرفانی
تخصص : برنامه نویس
@rezaerfani 5 سال پیش مطرح شد
0

در این معماری یک سرور بیشتر نداریم. بنابراین یک آدرس آی پی و یک آدرس یو آر ال بیشتر وجود نداره.لذا از سمت کلاینت نمی تونم بگم به کدام سرور بفرست.همه ی درخواست ها به سمت یک آی پی فرستاده می شه و سیستم عامل تصمیم می گیره اون رو به سمت کدام core بفرسته...دست من نیست


دانیال
@dani999dani99 5 سال پیش مطرح شد
0

من فکر کردم هر هسته ی شما یک سرور مستقل هستش آخه بالا گفتید که (انگار چند تا سرور داری) ، پس بالاخره یک سرور هستش یا چند تا!!
الان که گفتید یک سرور هستش تعجب کردم ! چون اگه یک سرور باشه شما از یک پورت استفاده می کنید و نباید مشکلی داشته باشید.
لطف کنید اطلاعات بیشتری در مورد ساختار سرورتون بدید تا بتونیم بهتر کمک کنیم. ایا این معماری اسم خاصی داره بگید تا تحقیق کنیم.


محمدرضا عرفانی
تخصص : برنامه نویس
@rezaerfani 5 سال پیش مطرح شد
0

دانیال عزیز :)
این سوالی که پرسیدم بعد از بیشتر از 1 ماه جستجو کردن و به جواب نرسیدن ، نوشتمش...
حتما باید در این حوزه کد نویسی کرده باشید تا بدونید چی می گم.
بازم دست گلت درد نکنه برادر


emadansari75
تخصص : senior node js developer
@emad.ansary 4 سال پیش آپدیت شد
0

سلام محمد جان، زمان زیادی گذشته ولی من پاسخ رو مینویسم تا اگر کسی مشکل مشابه داشته باشه بتونه به پاسخ برسه
متاسفانه این مشکل توی کلاستر وجود داره و اگر از worker thread های نود توی نسخه ی آخرش استفاده نمیکنی ، برای حل مشکت بهت redis socket io رو پیشنهاد میکنم ، درواقع سوکت هات یه share memory خواهند داشت داکیومنت های socket.io-redis میتونه بیشتر بهت کمک کنه (اینجا)
اگر بخوام توضیح بدم سوکت سرور رو به شکل معمول ران نمیکنی و از redis استفاده میکنی تا توی همه ی پراسس هات یکسان باشه، همونطور که میدونی cluster توی بهبود پرفرمنس درخواست های I/O توفیق چندانی نداره پس برای این قضیه هم نگرانی نداریم. پس اگر از adapter های redis توی هر پروسه استفاده کنیم مشکل حل میشه و کد یه چیزی شبیه کد زیر میشه :


var cluster = require('cluster');
var os = require('os');

if (cluster.isMaster) {
  // we create a HTTP server, but we do not use listen
  // that way, we have a socket.io server that doesn't accept connections
  var server = require('http').createServer();
  var io = require('socket.io').listen(server);
  var redis = require('socket.io-redis');

  io.adapter(redis({ host: 'localhost', port: 6379 }));

  setInterval(function() {
    // all workers will receive this in Redis, and emit
    io.emit('data', 'payload');
  }, 1000);

  for (var i = 0; i < os.cpus().length; i++) {
    cluster.fork();
  }

  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  }); 
}

if (cluster.isWorker) {
  var express = require('express');
  var app = express();

  var http = require('http');
  var server = http.createServer(app);
  var io = require('socket.io').listen(server);
  var redis = require('socket.io-redis');

  io.adapter(redis({ host: 'localhost', port: 6379 }));
  io.on('connection', function(socket) {
    socket.emit('data', 'connected to worker: ' + cluster.worker.id);
  });

  app.listen(80);
}```

محمدرضا عرفانی
تخصص : برنامه نویس
@rezaerfani 4 سال پیش مطرح شد
-1

ممنون از پاسخت... این مشکل رو با کتابخانه mubsub حلش کردم... در اونجا یک کانال تعریف میشه و هر درخواستی که از این کانال ارسال میشه، باعث میشه تمام پراسس ها ران بشن...
آقا چون در بالا گفته بودم، مبلغی ناقابل واریز میشه، یک شماره کارت بدید، تا بدقولی نکرده باشم.


emadansari75
تخصص : senior node js developer
@emad.ansary 4 سال پیش مطرح شد
1

ممنون از لطفت ولی نیازی نیست، حتما خودتم میدونی ما برنامه نویسا برای یادگیری خودمون به بقیه کمک میکنیم.
موفق باشی


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام