关闭 MySQL 后 Node.js 进程无法恢复,然后再打开
Posted
技术标签:
【中文标题】关闭 MySQL 后 Node.js 进程无法恢复,然后再打开【英文标题】:Node.js process cannot recover after MySQL turned off, then turn on 【发布时间】:2016-02-12 16:06:03 【问题描述】:我正在将 Node.js 与 mysql 和 restify 一起使用。
我有以下作为 REST API 的一部分运行的代码。它工作正常。
server.get('/test', function (req, res, next)
var query_string =
"SELECT DATE(date_transacted) AS transaction_date, " +
" MonthReports.tb AS MonthReports__tb " +
" FROM monthly_reports MonthReports " +
" WHERE ( date_transacted >= \'2015-01-00\' AND date_transacted <= \'2015-09-00\' ) ";
connection.query(
query_string
, function (err, rows, fields)
if (err) throw err;
res.send(rows);
);
);
如果我故意关闭 MySQL 数据库并调用 REST API 来运行查询,我会收到错误消息
致命错误后无法将查询入队。
此时,我打开了 MySQL 数据库。 node.js 进程无法恢复,并且在我进行 REST API 调用时不断出现相同的错误。 REST API 服务器已死。
如何使 Node.js REST API 服务器代码可恢复?
【问题讨论】:
【参考方案1】:我假设您在脚本内进行全局连接。
一种简单的方法是为每个请求创建一个连接:
server.get('/test', function (req, res, next)
var query_string =
"SELECT DATE(date_transacted) AS transaction_date, " +
" MonthReports.tb AS MonthReports__tb " +
" FROM monthly_reports MonthReports " +
" WHERE ( date_transacted >= \'2015-01-00\' AND date_transacted <= \'2015-09-00\' ) ";
var connection = getConnection(function connected(err)
if (err)
// error connecting to mysql! alert user
else
connection.query(
query_string
, function (err, rows, fields)
if (err) throw err;
res.send(rows);
);
);
);
上面的代码是伪代码,因为我不熟悉 node mysql 库。这将允许每个请求查看是否能够连接到 mysql,但代价是每个 Web 请求都有一个连接。
另一种策略是在发出查询时检查err
,如果出现错误,请尝试重新建立全局连接
server.get('/test', function (req, res, next)
var query_string =
"SELECT DATE(date_transacted) AS transaction_date, " +
" MonthReports.tb AS MonthReports__tb " +
" FROM monthly_reports MonthReports " +
" WHERE ( date_transacted >= \'2015-01-00\' AND date_transacted <= \'2015-09-00\' ) ";
connection.query(
query_string
, function (err, rows, fields)
if (err)
// Try to reconnect here instead of throwing error and stopping node process, and reissue query
res.send(rows);
);
);
【讨论】:
【参考方案2】:这个网站给出了完整的答案。归功于这篇文章的作者,而不是我。
https://www.exratione.com/2013/01/nodejs-connections-will-end-close-and-otherwise-blow-up/
/**
* @fileOverview A simple example module that exposes a getClient function.
*
* The client is replaced if it is disconnected.
*/
var mysql = require("mysql");
var client = mysql.createConnection(
host: "127.0.0.1",
database: "mydb",
user: "username",
password: "password"
);
/**
* Setup a client to automatically replace itself if it is disconnected.
*
* @param Connection client
* A MySQL connection instance.
*/
function replaceClientOnDisconnect(client)
client.on("error", function (err)
if (!err.fatal)
return;
if (err.code !== "PROTOCOL_CONNECTION_LOST")
throw err;
// client.config is actually a ConnectionConfig instance, not the original
// configuration. For most situations this is fine, but if you are doing
// something more advanced with your connection configuration, then
// you should check carefully as to whether this is actually going to do
// what you think it should do.
client = mysql.createConnection(client.config);
replaceClientOnDisconnect(client);
client.connect(function (error)
if (error)
// Well, we tried. The database has probably fallen over.
// That's fairly fatal for most applications, so we might as
// call it a day and go home.
//
// For a real application something more sophisticated is
// probably required here.
process.exit(1);
);
);
// And run this on every connection as soon as it is created.
replaceClientOnDisconnect(client);
/**
* Every operation requiring a client should call this function, and not
* hold on to the resulting client reference.
*
* @return Connection
*/
exports.getClient = function ()
return client;
;
【讨论】:
【参考方案3】:此答案摘自另一个链接nodejs mysql Error: Connection lost The server closed the connection
提取的代码;
var db_config =
host: 'localhost',
user: 'root',
password: '',
database: 'example'
;
var connection;
function handleDisconnect()
connection = mysql.createConnection(db_config); // Recreate the connection, since
// the old one cannot be reused.
connection.connect(function(err) // The server is either down
if(err) // or restarting (takes a while sometimes).
console.log('error when connecting to db:', err);
setTimeout(handleDisconnect, 2000); // We introduce a delay before attempting to reconnect,
// to avoid a hot loop, and to allow our node script to
); // process asynchronous requests in the meantime.
// If you're also serving http, display a 503 error.
connection.on('error', function(err)
console.log('db error', err);
if(err.code === 'PROTOCOL_CONNECTION_LOST') // Connection to the MySQL server is usually
handleDisconnect(); // lost due to either server restart, or a
else // connnection idle timeout (the wait_timeout
throw err; // server variable configures this)
);
handleDisconnect();
【讨论】:
以上是关于关闭 MySQL 后 Node.js 进程无法恢复,然后再打开的主要内容,如果未能解决你的问题,请参考以下文章
Web 进程在启动 node.js 后 60 秒内无法绑定到 $PORT