【问题标题】:Node.js process cannot recover after MySQL turned off, then turn on关闭 MySQL 后 Node.js 进程无法恢复,然后再打开
【发布时间】: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 服务器代码可恢复?

【问题讨论】:

    标签: javascript mysql node.js rest restify


    【解决方案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();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多