如何将nodeJS集群与mySQL池集群一起使用?

pri*_*ton 8 node.js node-mysql mysql-cluster node-cluster

快问

如果我创建一个包含4个worker(我的应用程序的4个实例)的节点集群应用程序,我应该使用mySQL池还是mysql池集群?如果我使用池,它将为每个应用程序创建一个池但如果我使用池集群,它将为每个应用程序创建4个池(总共16个).这是一个很好的实现还是会降低性能?

让我们举一个假的例子来说明我在问什么.我正在创建一个这样的nodeJS服务器应用程序.


首先,让我们为mysql数据库创建配置文件(重要的是我创建db worker的这个文件的最后一部分):

DBconfig.js

'use strict'
const mysql   = require('mysql'),
      workers = process.env.WORKERS || require('os').cpus().length,
      cluster = require('cluster');

//Local Database Settings
const local_settings = {
    user       : 'user',
    host       : '127.0.0.1',
    password   : 'pass',
    database   : 'dbname',
    debug      : false,
    dateStrings: true,
    connectionLimit     : 10,
    defaultSelector     : 'RR',
    multipleStatements  : true,
    removeNodeErrorCount: 1
};

let poolCluster = module.exports = mysql.createPoolCluster( local_settings );

//here I make one db worker for each app worker
for(let i = 0; i < workers; i++){
    poolCluster.add(`DBWORKER_${process.pid}_${i}`, local_settings);
}
Run Code Online (Sandbox Code Playgroud)

然后我创建一个全局库,在我的应用程序中使用,我有我的数据库连接功能

globalLib.js

'use strict'
const path        = require('path'),
      poolCluster = require(path.join('path','to_the','DBconfig.js'));

global.db = obj => {
  return new Promise( (resolve, reject) => {
    poolCluster.getConnection(function(err, connection){
        if(err) {reject(err);return}

        connection.query(obj.query, obj.params, function(){
            connection.release();
            if(!err) resolve(rows)
            else reject(err);
        });

        connection.on('error'), function(err){
            reject(err);
        });
    }
  })
}
Run Code Online (Sandbox Code Playgroud)

app.js

'use strict'
const express = require('express'),
      path    = require('path');
let   app     = module.exports = express();

//here I handle all with express.Router()
const index = require(path.join('path','to_my','index.js'));

app.use('/', index)
Run Code Online (Sandbox Code Playgroud)

最后我有一个从我启动服务器的群集文件(这里的一切很重要):

cluster.js

'use strict'
const path    = require('path'),
      cluster = require('cluster'),
      sockets = require(path.join('path_to','sockets.js')),
      app     = require(path.join('path_to','app.js')),
      pclust  = require(path.join('path_to', 'DBconfig.js')),
      workers = process.env.WORKERS || require('os').cpus().length;

if (cluster.isMaster) {

    for (var i = 0; i < workers; ++i) {
        var worker = cluster.fork();
    }

    cluster.on('disconnect', function(worker) {
        pclust.remove(`DBWORKER_${worker.process.pid}_*`);//remove all connections relative to this process pid
        var worker = cluster.fork();
    });
}
else {

    //Start Application
    var server = app.listen(8080, '127.0.0.1', function(){
        console.log('yeeeeey');
    });

    // initialize socket
    sockets.initialize(server,app);
}
Run Code Online (Sandbox Code Playgroud)

我们假设我有4个cpus,所以我的app.js会有4个实例.因此,我为每个应用程序中的每个cpu创建了一个数据库工作者,所以最后我有:

cpuID    server instances    db workers

 1            1                 4

 2            1                 4

 3            1                 4

 4            1                 4

 4            4                 16 ( TOTAL )
Run Code Online (Sandbox Code Playgroud)

这让我有了很多数据库工作者...问题是,这是一个很好的nodeJS集群和mySQL池集群的实现吗?如果不是哪种方式正确?

ima*_*ork 2

我也很好奇这个答案。我假设,随着处理器数量的增加,它通常会在请求较少的情况下表现更好,但在流量很大时,它会更好地使用。

在 app.js 文件中,我在 app.js 中使用这些包:

const cluster = require('cluster');
const http = require('http');
let osu = require('node-os-utils'); //get's number of cpus
var cpu = osu.cpu;
Run Code Online (Sandbox Code Playgroud)

我还安装了自动加农炮。

if(cluster.isMaster) {
  const availableCpus = cpu.count();

  console.log('clustering to', availableCpus, 'processes');
  for (let i = 0; i < availableCpus; i++) {
    cluster.fork();
  }

  cluster.on('online', function(worker) {
    console.log('worker:', worker.process.pid, 'is online');
  })

  cluster.on('exit', (worker, code, signal) => {
    if(code !== 0 && !worker.exitedAfterDisconnect) {
      console.log('Starting new worker:', worker.process.pid, + 'signal:', signal);
      cluster.fork();
    }
  })
}
else {

  app.get('/', function (req, res) {
    let i= 100000000; while (i>0) {i--}
    res.send();
  });

  app.listen(port, () => console.log("APP TEST: port %s", port));

}
Run Code Online (Sandbox Code Playgroud)

使用不带集群的自动加农炮:

使用 300 个连接、持续时间 20 秒的服务器性能

使用具有集群和 8 个工作人员的 autocannon:

使用 300 个连接、持续时间 20 秒和 8 个工作线程的服务器性能

此外,没有 Node.js 集群:44k 请求。使用 Node.js 集群和 8 个工作线程:40k 请求。

如果有人能对此做出解释,我会发现很有帮助。