2017-09-01 90 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