繁体   English   中英

带有 MySQL 连接的 Nodejs 集群

[英]Nodejs Cluster with MySQL connections

正在寻找有关 Nodejs 集群和连接到 mysql 服务器的方法的建议。 我们是为每个子进程打开一个连接还是只为所有进程打开一个连接? 还是我们为所有子进程创建一个连接池? 推荐的方法是什么?

单节点进程

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'example.org',
  user     : 'bob',
  password : 'secret'
});

connection.connect(function(err) {
  if (err) {
    console.error('error connecting: ' + err.stack);
    return;
  }

  console.log('connected as id ' + connection.threadId);
});

节点集群选项 1:

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
} else {
  // open one connection for each process
  var mysql      = require('mysql');
    var connection = mysql.createConnection({
      host     : 'example.org',
      user     : 'bob',
      password : 'secret'
    });

    connection.connect(function(err) {
      if (err) {
        console.error('error connecting: ' + err.stack);
        return;
      }

      console.log('connected as id ' + connection.threadId);
    });
}

选项2:

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

var mysql = require('mysql');
var pool  = mysql.createPool({
    connectionLimit : 10,
    host            : 'example.org',
    user            : 'bob',
    password        : 'secret'
});

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
} else {

  // accept http connections and query
  pool.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
     if (err) throw err;

     console.log('The solution is: ', rows[0].solution);
  });
}

经过一些试验和错误后,我使用了选项 2,它运行良好。 全局创建连接并在集群中使用。

每次需要查询的时候,getConnection。

pool.getConnection(function(err, connection) {
        if(err) {
            console.log('Error getting sql connection');
            console.dir(err);

            if(typeof connection !== "undefined")
                connection.release();

            callback(err);
        }

        if(typeof cb === "undefined") {
            //console.log('with 2 params');
            connection.query( sql, function(err, rows) {
                connection.release();
                console.dir(sql);
                // console.dir('data=>' + data);

                if(err) {
                    console.log('err:' + err);
                    callback(err, rows);
                }else{
                    console.log( rows );
                    callback(err, rows);
                }
            });
        } else {
            // console.log('with 3 params:' + cb);
            connection.query( sql, data, function(err, rows){
                connection.release();
                console.log(sql);
                console.dir(data);

                if(err) {
                    console.log('err:' + err);
                    callback(err, rows);
                }else{
                    console.log( rows );
                    callback(err, rows);
                }

            });
        }
    });
}

我相信正确的答案是,这一切都取决于? 如果您运行并发操作(异步等),您可能需要一个池。 但是如果您只是嵌套查询,那么单个共享连接应该没问题。

我更喜欢使用池(甚至在工作人员内部),仅仅是因为您可以免费获得一些错误处理和健壮性(连接在它们死亡时重新创建,有一个带有超时的操作队列等)。 到目前为止,我还没有发现任何缺点......

将为每个工作线程重新创建池,并且您的集群应用程序中将有多个连接池

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM