节点 js setInterval 和 nohup 的进程产生问题
Process-spawning issue with node js setInterval and 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
});
它一直运行良好,但最近我开始在 Web 应用程序中收到错误提示 "User already has more than 'max_user_connections' active connections",并且在使用 MySQL 的 "show processlist" 进行数据库级别调查后,我很快看到 spawning/dying 连接 - 我需要做的就是 kill/restart pushNotifications.js 脚本,一切都恢复正常。
我希望有人看到我的代码有问题,可能无法处理可能导致进程以比每 15 秒更规律的间隔重复生成的场景。感谢任何想法,因为我没有进一步诊断的想法。
您正在为每个客户端连接和每个时间间隔创建一个新的数据库连接,这是相当浪费的。
最好创建一个大小合适的 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);
});
一些补充说明:
- 一旦客户端断开连接,其关联的时间间隔就不是 cleared/stopped。在某些时候这将开始引起问题,因为它的 运行 代表不再存在的客户端进行查询;您可能应该在
disconnect
事件上使用侦听器来调用 clearInterval
以在服务器检测到客户端断开连接时清理资源。
- 您的示例代码不会显示数据库查询是否特定于每个客户端。如果不是,您应该将间隔完全移到
io.on()
块之外,并使用 Socket.IO 广播向所有连接客户端发送数据(而不是 运行 每个客户端的完全相同的查询分别)
我是 运行 一个 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
});
它一直运行良好,但最近我开始在 Web 应用程序中收到错误提示 "User already has more than 'max_user_connections' active connections",并且在使用 MySQL 的 "show processlist" 进行数据库级别调查后,我很快看到 spawning/dying 连接 - 我需要做的就是 kill/restart pushNotifications.js 脚本,一切都恢复正常。
我希望有人看到我的代码有问题,可能无法处理可能导致进程以比每 15 秒更规律的间隔重复生成的场景。感谢任何想法,因为我没有进一步诊断的想法。
您正在为每个客户端连接和每个时间间隔创建一个新的数据库连接,这是相当浪费的。
最好创建一个大小合适的 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);
});
一些补充说明:
- 一旦客户端断开连接,其关联的时间间隔就不是 cleared/stopped。在某些时候这将开始引起问题,因为它的 运行 代表不再存在的客户端进行查询;您可能应该在
disconnect
事件上使用侦听器来调用clearInterval
以在服务器检测到客户端断开连接时清理资源。 - 您的示例代码不会显示数据库查询是否特定于每个客户端。如果不是,您应该将间隔完全移到
io.on()
块之外,并使用 Socket.IO 广播向所有连接客户端发送数据(而不是 运行 每个客户端的完全相同的查询分别)