节点 MySQL 连接池 - 等待数据库启动
Node MySQL Connection Pool - wait for database to start
如何检查 MySQL 数据库是否已准备好接受来自节点 MySQL 连接池的某些查询?
我有一个由以下容器组成的 Docker 环境:
- 容器 1:网络服务器
- 容器 2:api
- 容器 3:数据库
数据库容器运行 MySQL 数据库。 api 容器连接到该数据库。所有三个容器同时启动。 Web 服务器容器在 0.5 秒后启动。 api 容器在 2 秒后启动。数据库服务器在 20 秒后启动。
目前,api 尝试在数据库启动和 运行 之前访问数据库的表。这会导致 connection refused 之类的错误。当 MySQL 数据库尚未启动时,以下代码段总是以消息 "Error querying database!" 结束:
const sql: string = 'SELECT * FROM sometable;';
MySQL.createPool({
connectionLimit: 10,
acquireTimeout: 30000,
waitForConnections: true,
database: 'mydatabase',
host: 'localhost',
multipleStatements: true,
password: 'mypassword',
user: 'root',
}).query(sql, (err, result) => {
if (result) {
console.log('Successfully queried database.');
} else {
console.log('Error querying database!');
}
});
正在使用的版本:
OS: Ubuntu 19.10
Node: v13.6.0
MySQL (Node API): "@types/mysql": "2.15.8" and "mysql": "2.17.1"
MySQL (Docker Database): mysql:5.7.28
TypeScript: 3.7.4
我想检查(并等待)api 中的数据库准备情况,可能使用我用于查询的连接池。这可能吗?
重试连接 setTimeout()
:
(使用 Javascript 而不是打字稿回答)
'use strict';
const dbpool = require('mysql').createPool({
connectionLimit: 10,
acquireTimeout: 30000,
waitForConnections: true,
database: 'mydatabase',
host: 'localhost',
multipleStatements: true,
password: 'mypassword',
user: 'root',
});
const sql = 'SELECT * FROM sometable;';
const attemptConnection = () =>
dbpool.getConnection((err, connection) => {
if (err) {
console.log('error connecting. retrying in 1 sec');
setTimeout(attemptConnection, 1000);
} else {
connection.query(sql, (errQuery, results) => {
connection.release();
if (errQuery) {
console.log('Error querying database!');
} else {
console.log('Successfully queried database.');
}
});
}
});
attemptConnection();
这是我的测试运行:
$ sudo service mysql stop; node test.js & sudo service mysql start
[1] 24737
error connecting. retrying in 1 sec
error connecting. retrying in 1 sec
$ Successfully queried database.
仅供参考,程序永远不会结束,因为它需要 dbpool.end()
;
您的 API 应该尝试连接到数据库,并设置超时和一定的连接尝试阈值。但是,对于这种情况,有现成的解决方案。
尝试使用 wait-for-mysql 模块。
waitForMy = require 'wait-for-mysql'
config =
username: user
password: pass
quiet: true
query: 'SELECT 1'
waitForMy.wait(config)
这里有一个变体,但不需要 mysql 池化。我在我的服务器上使用它并且它确实有效:
const mysql = require('mysql')
var db // global, to use later to db.query
var dbInfo = {
host : 'example.org',
database : 'some_database',
user : 'bob',
password : 'secret'
}
function connectToDb(callback) {
const attemptConnection = () => {
console.log('Attempting to connect to db')
dbInfo.connectTimeout = 2000 // same as setTimeout to avoid server overload
db = mysql.createConnection(dbInfo)
db.connect(function (err) {
if (err) {
console.log('Error connecting to database, try again in 1 sec...')
db.destroy() // end immediately failed connection before creating new one
setTimeout(attemptConnection, 2000)
} else {
callback()
}
})
}
attemptConnection()
}
// now you simply call it with normal callback
connectToDb( () => {
console.log('Connection successfully')
// do some queries
db.query(..)
})
如何检查 MySQL 数据库是否已准备好接受来自节点 MySQL 连接池的某些查询?
我有一个由以下容器组成的 Docker 环境:
- 容器 1:网络服务器
- 容器 2:api
- 容器 3:数据库
数据库容器运行 MySQL 数据库。 api 容器连接到该数据库。所有三个容器同时启动。 Web 服务器容器在 0.5 秒后启动。 api 容器在 2 秒后启动。数据库服务器在 20 秒后启动。
目前,api 尝试在数据库启动和 运行 之前访问数据库的表。这会导致 connection refused 之类的错误。当 MySQL 数据库尚未启动时,以下代码段总是以消息 "Error querying database!" 结束:
const sql: string = 'SELECT * FROM sometable;';
MySQL.createPool({
connectionLimit: 10,
acquireTimeout: 30000,
waitForConnections: true,
database: 'mydatabase',
host: 'localhost',
multipleStatements: true,
password: 'mypassword',
user: 'root',
}).query(sql, (err, result) => {
if (result) {
console.log('Successfully queried database.');
} else {
console.log('Error querying database!');
}
});
正在使用的版本:
OS: Ubuntu 19.10
Node: v13.6.0
MySQL (Node API): "@types/mysql": "2.15.8" and "mysql": "2.17.1"
MySQL (Docker Database): mysql:5.7.28
TypeScript: 3.7.4
我想检查(并等待)api 中的数据库准备情况,可能使用我用于查询的连接池。这可能吗?
重试连接 setTimeout()
:
(使用 Javascript 而不是打字稿回答)
'use strict';
const dbpool = require('mysql').createPool({
connectionLimit: 10,
acquireTimeout: 30000,
waitForConnections: true,
database: 'mydatabase',
host: 'localhost',
multipleStatements: true,
password: 'mypassword',
user: 'root',
});
const sql = 'SELECT * FROM sometable;';
const attemptConnection = () =>
dbpool.getConnection((err, connection) => {
if (err) {
console.log('error connecting. retrying in 1 sec');
setTimeout(attemptConnection, 1000);
} else {
connection.query(sql, (errQuery, results) => {
connection.release();
if (errQuery) {
console.log('Error querying database!');
} else {
console.log('Successfully queried database.');
}
});
}
});
attemptConnection();
这是我的测试运行:
$ sudo service mysql stop; node test.js & sudo service mysql start
[1] 24737
error connecting. retrying in 1 sec
error connecting. retrying in 1 sec
$ Successfully queried database.
仅供参考,程序永远不会结束,因为它需要 dbpool.end()
;
您的 API 应该尝试连接到数据库,并设置超时和一定的连接尝试阈值。但是,对于这种情况,有现成的解决方案。
尝试使用 wait-for-mysql 模块。
waitForMy = require 'wait-for-mysql' config = username: user password: pass quiet: true query: 'SELECT 1' waitForMy.wait(config)
这里有一个变体,但不需要 mysql 池化。我在我的服务器上使用它并且它确实有效:
const mysql = require('mysql')
var db // global, to use later to db.query
var dbInfo = {
host : 'example.org',
database : 'some_database',
user : 'bob',
password : 'secret'
}
function connectToDb(callback) {
const attemptConnection = () => {
console.log('Attempting to connect to db')
dbInfo.connectTimeout = 2000 // same as setTimeout to avoid server overload
db = mysql.createConnection(dbInfo)
db.connect(function (err) {
if (err) {
console.log('Error connecting to database, try again in 1 sec...')
db.destroy() // end immediately failed connection before creating new one
setTimeout(attemptConnection, 2000)
} else {
callback()
}
})
}
attemptConnection()
}
// now you simply call it with normal callback
connectToDb( () => {
console.log('Connection successfully')
// do some queries
db.query(..)
})