NodeでのMySQL接続プールの交換およびMySQL接続プールクラスタの使用
11154 ワード
NodeでのMySQL接続プールの交換およびMySQL接続プールクラスタの使用
ビジネスロジックを行うには、ユーザーの前にどれだけ派手なものを並べても、結局はユーザーがデータベースと交流しています.
プロジェクトを行うたびに、データベース接続プールを使用することはできませんが、異なる言語と異なるデータベース接続プールの調査と選択には数日かかり、本当に書かなければなりません.テストは本当にあなたのニーズに合っているかどうか、また数日かかります.
Nodeでは、私が最初に選んだのはgeneric poolで、前回の休暇中に呼び出されたので、ホームページを見て、更新がタイムリーで、悪くないと感じました.
残念なことに、この接続プールはMySQLサービス側が自発的に接続を閉じた後、自動的に再接続しないだけでなく、Nodeプロセスを掛けることも証明されています.私が設定した問題なのか、それとも他の問題なのか、ちょうどMySQLモジュールが接続プールを持っていることを調査するきっかけがあります.
これで、接続プールが完了し、
しかし、問題は大きくありません.その後、需要に応じて、
プロファイルは次のとおりです:プライマリプロファイル:
クラスタノードプロファイル:
主な参考: generic pool Node MySQL Nodejs mysql pool使用例 MySQLのwait_timeout
ビジネスロジックを行うには、ユーザーの前にどれだけ派手なものを並べても、結局はユーザーがデータベースと交流しています.
プロジェクトを行うたびに、データベース接続プールを使用することはできませんが、異なる言語と異なるデータベース接続プールの調査と選択には数日かかり、本当に書かなければなりません.テストは本当にあなたのニーズに合っているかどうか、また数日かかります.
Nodeでは、私が最初に選んだのはgeneric poolで、前回の休暇中に呼び出されたので、ホームページを見て、更新がタイムリーで、悪くないと感じました.
/**
* Created by randy on 2017/6/29.
*/
var genericPool = require('generic-pool');
var DbDriver = require('mysql');
var settings = require('./settings');
/**
* Step 1 - Create pool using a factory object
*/
const factory = {
create: function () {
return new Promise(function (resolve, reject) {
var client = DbDriver.createConnection({
host: settings.mysql.host,
port: settings.mysql.port,
database: settings.mysql.database,
user: settings.mysql.user,
password: settings.mysql.password,
charset: settings.mysql.charset
});
client.connect(function (err) {
if (err) {
console.log("SQL CONNECT ERROR: ", err);
} else {
console.log("SQL CONNECT SUCCESSFUL.");
resolve(client)
}
});
})
},
destroy: function (client) {
return new Promise(function (resolve) {
client.on('end', function () {
resolve()
});
client.disconnect()
})
},
error: function () {
console.info('AAAAAAAA');
this.create();
}
};
var opts = {
max: 10, // maximum size of the pool
min: 5, // minimum size of the pool
// acquireTimeoutMillis: 2,
idleTimeoutMillis: 1000,
log: true
};
var myPool = genericPool.createPool(factory, opts);
/**
* Step 2 - Use pool in your code to acquire/release resources
*/
// acquire connection - Promise is resolved
// once a resource becomes available
const resourcePromise = myPool.acquire()
.then(function (resource) {
console.log('resource');
})
.catch(function (err) {
console.log(err);
return myPool.drain()
});
module.exports = {
doGetQuery: function (res, procName, handler) {
var paraArray = [];
var stmt = "CALL " + procName + "()";
resourcePromise.then(function (client) {
client.query(stmt, paraArray, function (err, rows, fields) {
if (err) {
throw err;
}
handler(res, rows);
//myPool.release(client);
});
})
.catch(function (err) {
// handle error - this is generally a timeout or maxWaitingClients
// error
});
},
doPostQuery: function (req, res, procName, handler) {
req.on("data", function (chunk) {
var params = JSON.parse(chunk.toString());
var paraArray = [];
var stmt = "CALL " + procName + "(";
for (var param in params) {
stmt = stmt + "?, ";
paraArray.push(params[param]);
}
stmt = stmt.substring(0, stmt.length - 2) + ")";
resourcePromise.then(function (client) {
client.query(stmt, paraArray, function (err, rows, fields) {
if (err) {
throw err;
}
handler(res, rows);
//myPool.release(client);
});
})
.catch(function (err) {
// handle error - this is generally a timeout or maxWaitingClients
// error
});
}
)
}
};
/**
* Step 3 - Drain pool during shutdown (optional)
*/
// Only call this once in your application -- at the point you want
// to shutdown and stop using this pool.
/*
myPool.drain().then(function() {
myPool.clear();
});
*/
残念なことに、この接続プールはMySQLサービス側が自発的に接続を閉じた後、自動的に再接続しないだけでなく、Nodeプロセスを掛けることも証明されています.私が設定した問題なのか、それとも他の問題なのか、ちょうどMySQLモジュールが接続プールを持っていることを調査するきっかけがあります.
var mysql = require('mysql');
var settings = require("./settings");
var config = {
host: settings.mysql.host,
port: settings.mysql.port,
database: settings.mysql.database,
user: settings.mysql.user,
password: settings.mysql.password,
charset: settings.mysql.charset,
acquireTimeout: settings.mysql.acquireTimeout,
waitForConnections: settings.mysql.waitForConnections,
connectionLimit: settings.mysql.connectionLimit,
queueLimit: settings.mysql.queueLimit
};
var pool = mysql.createPool(config);
pool.getConnection(function (err, connection) {
console.log(err);
});
module.exports = {
doGetQuery: (res, procName, handler) => {
let paraArray = [];
let stmt = "CALL " + procName + "()";
pool.getConnection(function (err, connection) {
connection.query(stmt, paraArray, function (err, rows, fields) {
if (err) {
throw err;
}
handler(res, rows);
});
connection.release();
});
},
doPostQuery: function (req, res, procName, handler) {
req.on("data", function (chunk) {
let params = JSON.parse(chunk.toString());
let paraArray = [];
let stmt = "CALL " + procName + "(";
for (let param in params) {
stmt = stmt + "?, ";
paraArray.push(params[param]);
}
stmt = stmt.substring(0, stmt.length - 2) + ")";
pool.getConnection((err, connection) => {
connection.query(stmt, paraArray, function (err, rows, fields) {
if (err) {
throw err;
}
handler(res, rows);
});
connection.release();
});
}
)
}
};
これで、接続プールが完了し、
Generic pool
MySQL Pool
と比較して、最小接続数などの共通接続プールの構成がないという欠点があります.ネット上では、データベース接続プールの共通構成をまとめています.{
connectionLimit : 50,
queueWaitTimeout : 10000, // Same as acquireTimeout.
pingCheckInterval : 10000, // The connection used in 10 seconds is reused without ping check.
startConnections : 10, // 10 connections are created when the pool is started.
minSpareConnections : 10, // 10 spare connections should be kept in the pool at all times.
maxSpareConnections : 20, // No more than 20 spare connections.
spareCheckInterval : 300000 // Check the spare connections every 5 minutes.
}
しかし、問題は大きくありません.その後、需要に応じて、
MySQL Pool
にクラスタを追加しました.これはNode MySQL
を見たときに何気なく発見されました.これはいいものです.加えて:var mysql = require('mysql');
var settings = require("./settings");
var poolcfg = require("./msqNodeCfg");
var poolCluster = mysql.createPoolCluster();
poolCluster.add(settings.mysqlPoolCluster);
poolCluster.add('X', poolcfg.node01);
poolCluster.add('Y', poolcfg.node02);
poolCluster.add('Z', poolcfg.node03);
module.exports = {
doGetQuery: (res, procName, handler) => {
let paraArray = [];
let stmt = "CALL " + procName + "()";
poolCluster.getConnection(function (err, connection) {
connection.query(stmt, paraArray, function (err, rows, fields) {
if (err) {
throw err;
}
handler(res, rows);
});
connection.release();
});
},
doPostQuery: function (req, res, procName, handler) {
req.on("data", function (chunk) {
let params = JSON.parse(chunk.toString());
let paraArray = [];
let stmt = "CALL " + procName + "(";
for (let param in params) {
stmt = stmt + "?, ";
paraArray.push(params[param]);
}
stmt = stmt.substring(0, stmt.length - 2) + ")";
poolCluster.getConnection((err, connection) => {
connection.query(stmt, paraArray, function (err, rows, fields) {
if (err) {
throw err;
}
handler(res, rows);
});
connection.release();
});
}
)
}
};
プロファイルは次のとおりです:プライマリプロファイル:
mysql: {
host: "127.0.0.1",
port: 3306,
user: "root",
password: "root",
database: "db_test",
charset: "utf8"
},
mysqlPool: {
acquireTimeout: 10000,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
},
mysqlPoolCluster: {
canRetry: true,
removeNodeErrorCount: 5,
restoreNodeTimeout: 0,
defaultSelector: "RR"
}
クラスタノードプロファイル:
var settings = require("./settings");
module.exports = {
node01: {
host: '192.168.1.240',
port: settings.mysql.port,
database: settings.mysql.database,
user: settings.mysql.user,
password: "root",
charset: settings.mysql.charset,
acquireTimeout: settings.mysqlPool.acquireTimeout,
waitForConnections: settings.mysqlPool.waitForConnections,
connectionLimit: settings.mysqlPool.connectionLimit,
queueLimit: settings.mysqlPool.queueLimit
},
node02: {
host: "192.168.1.122",
port: settings.mysql.port,
database: settings.mysql.database,
user: settings.mysql.user,
password: "root",
charset: settings.mysql.charset,
acquireTimeout: settings.mysqlPool.acquireTimeout,
waitForConnections: settings.mysqlPool.waitForConnections,
connectionLimit: settings.mysqlPool.connectionLimit,
queueLimit: settings.mysqlPool.queueLimit
},
node03: {
host: '192.168.1.105',
port: settings.mysql.port,
database: settings.mysql.database,
user: settings.mysql.user,
password: "root",
charset: settings.mysql.charset,
acquireTimeout: settings.mysqlPool.acquireTimeout,
waitForConnections: settings.mysqlPool.waitForConnections,
connectionLimit: settings.mysqlPool.connectionLimit,
queueLimit: settings.mysqlPool.queueLimit
}
};
主な参考: