2017-09-01 58 views
1

我运行一个node.js脚本,每隔15秒向所有连接的Web应用程序用户广播数据。它使用此命令运行...节点js setInterval和nohup的进程产卵问题

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 

}); 

它一直工作得很好,但最近我开始变得在Web应用程序的错误说法“用户已经有超过'max_user_connections'活动连接“,并且通过使用MySQL的”show processlist“在数据库级调查,我看到迅速产卵/死亡连接 - 我需要做的就是杀死/重新启动pushNotifications.js脚本,一切都是恢复正常。

我希望是有人看到我的代码有问题,可能无法处理可能导致进程反复产卵的间隔比每隔15秒更频繁的场景。欣赏任何想法,因为我没有想法进一步诊断这一点。

回答

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广播发送所有连接的客户端的数据(而不是运行完全相同的查询为每个客户单独)
+0

非常感谢对于一些伟大的想法 - 我将实施这些,看看是否可以阻止这种行为 - 至少他们更有效,所以绝对值得加入! – d3wannabe