节点js setInterval和nohup的进程生成问题

时间:2017-09-01 13:21:00

标签: javascript mysql node.js nohup

我正在运行node.js脚本,每隔15秒向所有连接的网络应用用户广播数据。它正在运行此命令...

nohup node /pushNotifications.js &

这就是代码......

var https = require('https'), fs = require('fs'), app = require("express"), key = fs.readFileSync('apache.key', 'utf8'), cert  = fs.readFileSync('apache.crt', 'utf8')
var server = https.createServer({key: key, cert: cert}, app); 

server.listen(8080)
var io = require("socket.io").listen(server);
var mysql = require('mysql');

function handler (req, res) {
}

io.on('connection', function (socket) {

  setInterval( function() {

    var connection = mysql.createConnection({
      host: 'db.server.com', user: 'dbuser', password: 'dbpass', database: 'dbname', port: 3306
    });

    connection.connect(function(err){
    });

    connection.query('SELECT someColumn FROM someTable ', function(err, rows, fields) {
      if (!err) {
        socket.emit('notifications', JSON.stringify(rows));
        connection.end();
      } else {
        connection.end(); 
      }
    }); 

  }, 15000); //15 seconds

}); 

它一直运行良好,但最近我开始在网络应用中遇到错误,并且#34;用户已经拥有超过' max_user_connections'活动连接",并且在使用MySQL"显示进程列表"进行数据库级别调查时,我看到快速产生/死亡连接 - 我需要做的就是杀死/重新启动pushNotifications.js脚本,一切都恢复正常。

我希望有人看到我的代码出现问题,可能无法处理可能导致进程以每15秒更经常的间隔重复生成的方案。欣赏任何想法,因为我没有进一步诊断这个想法。

1 个答案:

答案 0 :(得分:1)

您为每个客户端连接创建了一个新的数据库连接,这非常浪费。

创建一个体积适中的connection pool一次,然后使用其中的连接会好得多:

let pool  = mysql.createPool({
  connectionLimit : 10, // this may require tweaking depending on # of clients
  ...
});

io.on('connection', function(socket) {
  setInterval(function() {
    pool.query('SELECT someColumn FROM someTable ', function(err, rows, fields) {
      if (!err) {
        socket.emit('notifications', JSON.stringify(rows));
        connection.end();
      } else {
        connection.end(); 
      }
    }); 
  }, 15000);
});

其他一些评论:

  • 一旦客户端断开连接,其关联间隔就不会被清除/停止。在某些时候会开始引起问题,因为它代表不再存在的客户端运行查询;您应该使用disconnect事件上的侦听器来调用clearInterval以在服务器检测到客户端断开连接时清理资源。
  • 您的示例代码不会显示数据库查询是否特定于每个客户端。如果不是,则应将间隔完全移至io.on()块之外,并使用Socket.IO广播向所有连接客户端发送数据(而不是分别为每个客户端运行完全相同的查询)