Nodejs的fork进程执行mysql操作,内存不断增加

Nodejs的fork进程执行mysql操作,内存不断增加

nodejs的fork进程mysql内存不断增加。

代码:

var mysql = require('mysql');
var sqlForks = require('fork-list');
var db_options = {
    host: 'localhost',
    port: 3306,
    user: 'root',
    password: '123',
    database: '123'
};
var client = mysql.createConnection(db_options);
var moment = require('moment');
var date = new moment().format("YYYYMMDD");
var datetime = '';

sqlForks.proc(function(sqlString){ client = mysql.createConnection(db_options); client.connect(function(err) { if(err) { debug_log('connect db error: ’ + err); } }); client.query(sqlString, function(err, results, fields) {
if(err) { datetime = new moment().format(“YYYY-MM-DD HH:mm:ss”); debug_log(datetime + " mysql error:" + err); } }); client.end(); });

功能: 后台forks进程一直会收到sql的query语句,其实不断开mysql连接是最好的了。

现在问题: 每个forks进程内存一直在增加。


7 回复

Node.js 的 fork 进程执行 MySQL 操作,内存不断增加

问题描述

在使用 Node.js 的 fork 进程执行 MySQL 操作时,发现每个 fork 进程的内存占用不断增加。这可能导致系统资源耗尽,影响应用性能。

代码示例

以下是一个简单的示例代码,展示了如何使用 fork 进程来执行 MySQL 查询:

var mysql = require('mysql');
var sqlForks = require('fork-list');
var db_options = {
    host: 'localhost',
    port: 3306,
    user: 'root',
    password: '123',
    database: '123'
};

var moment = require('moment');
var date = new moment().format("YYYYMMDD");
var datetime = '';

sqlForks.proc(function(sqlString){
    var client = mysql.createConnection(db_options);
    client.connect(function(err) {
        if(err) {
            debug_log('connect db error: ' + err);
        }
    });
    client.query(sqlString, function(err, results, fields) {  
        if(err) {
            datetime = new moment().format("YYYY-MM-DD HH:mm:ss");
            debug_log(datetime + " mysql error:" + err);
        }
    });
    client.end();
});

问题分析

从上面的代码中可以看到,每次接收到 SQL 查询请求时,都会创建一个新的 MySQL 连接并立即关闭它。虽然看起来像是正确的做法,但实际上每次创建和关闭连接都会消耗一定的资源,导致内存不断增加。

解决方案

为了减少内存占用,可以考虑以下两种方法:

  1. 复用连接:在一个固定的时间段内复用同一个数据库连接,而不是每次都创建新的连接。
  2. 优化连接管理:确保在连接完成后正确地关闭连接,避免内存泄漏。
示例代码(改进版)
var mysql = require('mysql');
var sqlForks = require('fork-list');
var db_options = {
    host: 'localhost',
    port: 3306,
    user: 'root',
    password: '123',
    database: '123'
};

var moment = require('moment');
var date = new moment().format("YYYYMMDD");
var datetime = '';
var client;

// 初始化连接
function initClient() {
    client = mysql.createConnection(db_options);
    client.connect(function(err) {
        if(err) {
            debug_log('connect db error: ' + err);
        }
    });
}

initClient();

sqlForks.proc(function(sqlString){
    client.query(sqlString, function(err, results, fields) {  
        if(err) {
            datetime = new moment().format("YYYY-MM-DD HH:mm:ss");
            debug_log(datetime + " mysql error:" + err);
        }
    });
});

process.on('exit', function() {
    if(client) {
        client.end();
    }
});

在这个改进版的代码中,我们只初始化一次数据库连接,并在进程退出时关闭连接。这样可以显著减少内存占用,提高应用的稳定性。

结论

通过复用数据库连接和正确管理连接生命周期,可以有效减少内存占用,提高 Node.js 应用的性能和稳定性。


mysql的client资源怎么释放

改成pool方式了,但是内存还是会慢慢上去,只有一个客户端在发数据测试。 代码: sqlForks.proc(function(sqlString){ client.getConnection(function(err, connection){ connection.query(sqlString, function(err, results, fields) {
if(err) { datetime = new moment().format(“YYYY-MM-DD HH:mm:ss”); debug_log(datetime + " mysql error:" + err); } }); connection.release(); }); });

fork-list这个模块 确认没有什么问题么 github上都没人关注过

感觉是fork-list的问题,换compute-cluster

你代码里面的函数调用有问题吧?看起来像是同步的写法

问题分析

在你的代码中,每个fork进程在每次处理SQL查询时都会创建一个新的MySQL连接并立即关闭它。这种频繁的连接和断开会导致内存不断增加,因为Node.js的垃圾回收机制需要时间来释放这些连接占用的资源。

解决方案

为了优化内存使用,可以考虑在fork进程中维护一个持久化的数据库连接。这样可以避免频繁地创建和销毁连接,从而减少内存泄漏的风险。

示例代码

var mysql = require('mysql');
var sqlForks = require('fork-list');
var db_options = {
    host: 'localhost',
    port: 3306,
    user: 'root',
    password: '123',
    database: '123'
};

// 创建一个持久化的数据库连接
var client = mysql.createConnection(db_options);

client.connect(function(err) {
    if (err) {
        debug_log('connect db error: ' + err);
    }
});

sqlForks.proc(function(sqlString) {
    client.query(sqlString, function(err, results, fields) {  
        if(err) {
            datetime = new moment().format("YYYY-MM-DD HH:mm:ss");
            debug_log(datetime + " mysql error:" + err);
        }
    });
});

process.on('exit', function() {
    // 在进程退出时断开数据库连接
    client.end();
});

解释

  1. 持久化连接:在fork进程中创建一个持久化的数据库连接,并保持该连接始终打开。
  2. 错误处理:确保在处理SQL查询时正确处理错误。
  3. 资源清理:在进程退出时通过process.on('exit', ...)断开数据库连接,确保资源得到及时释放。

通过这种方式,你可以显著减少内存占用,并提高程序的性能和稳定性。

回到顶部