如何使用Socket.io / Node.js服务器获得零停机时间?

时间:2018-01-24 00:21:42

标签: node.js socket.io

我有一个运行Socket.io的Node.js Web服务器。我发现如果脚本中发生一个错误,整个服务器崩溃了。所以我试图找到一个解决方案,以便在应用程序投入生产时保持服务器正常运行。我找到了一个看起来很有希望的答案,但是当我尝试在我的代码上实现它时,并没有解决我的特定问题:How do I prevent node.js from crashing? try-catch doesn't work

修改

到目前为止我修复的内容:我现在让PM2在崩溃时自动重启脚本,现在我已经设置了Redis并将用户会话数据存储在其中。

我的代码目前设置如下:

编辑#2 :在整天学习和处理代码之后,再次稍微编辑代码以包含" sticky-session"逻辑。在编辑代码之后,每1秒就不再有奇怪的套接字连接,看起来(我不完全确定)套接字都与工作人员同步。当脚本崩溃时,应用程序(不是PM2)会生成一个新进程,这似乎很好。但是当一个工作人员崩溃时,用户仍然需要再次刷新页面以刷新他们的会话并获得新的套接字,这是一个大问题...

var fs = require('fs');
  https = require('https'),
  express = require('express'),
  options = {
    key: fs.readFileSync('/path/to/privkey.pem'),
    cert: fs.readFileSync('/path/to/fullchain.pem')
  },
  cluster = require('cluster'), // not really sure how to use this
  net = require('net'), // not really sure what to do here
  io = require('socket.io'),
  io_redis = require('socket.io-redis'), // not really sure how to use this
  sticky = require('sticky-session'),
  os = require('os');
  var numCPUs = os.cpus().length;
  var server = https.createServer(options,app, function(req, res) {
    res.end('worker: '+cluster.worker.id);
  });

if(!sticky.listen(server, 3000) {
  // Master code
  for(var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  server.once('listening', function() {
    console.log('server started on port 3000');
  });
}
else {
  // Worker code
  var 
    io = io(server),
    io.adapter(io_redis({host: 'localhost', port: 6379})),
    getUser = require('./lib/getUser'),
    loginUser = require('./lib/loginUser'),
    authenticateUser = require('./lib/authenticateUser'),
    client = require('./lib/redis'); // connect to redis

  client.on("error", function(err) {
    console.log("Error "+err);
  });

  io.on('connection', function(socket){
    // LOTS OF SOCKET EVENTS / REDIS USER SESSION MANAGEMENT / APP
  });

}

我尝试使用&#34; cluster&#34;,但我不确定如何使其正常工作,因为它涉及多个&#34; worker&#34;,我相信套接字混合之间。我甚至不确定我的代码的哪些部分(&#34;需要&#34;函数等)进入哪个&#34; cluster&#34;代码块(主/工),或如何保持套接字同步。有些事情是不对的。

我假设我需要使用npm包socket.io-redis和/或sticky-session来保持套接字同步? (不知道如何实现这一点)。不幸的是,在网上或我正在阅读的有关node.js集群socket.io的书籍中,没有任何好的例子

有人可以提供一个基本的代码示例,说明我的代码部分在哪里,或者如何实现?我将不胜感激。目标是:

1)如果服务器(节点集群进程)崩溃,则套接字在重新启动后仍然可以工作(或其他工作程序生成)。

例如,如果两个用户(两个套接字)正在进行私人消息对话,然后发生崩溃,则在崩溃后PM2自动重新启动(生成新的集群进程)后仍应传递消息。我遇到的问题:如果服务器崩溃,即使在自动重启后,消息也会停止发送给用户。

2)套接字应该与不同的集群进程一起同步。

1 个答案:

答案 0 :(得分:0)

  

如何通过...

获得零停机时间

你没有。

根本不可能有任何东西。你问的是错误的问题。试试这些:

  • 如何捕捉和处理我能预测的错误?
  • 当我无法预测错误时,如何优雅地失败?
  • 如何有效地将应用程序中的错误与客户端与其交互的错误分开?
  • 如何构建分布式系统?
  • 如何部署和扩展具有容错能力的系统?
  • 我有[单点故障XYZ],如何分发[XYZ]以将其删除?
  • 哪些系统监控对[某些技术]有用?
  • 如何为[重复出现问题X]设置自动化?

等。等