NodeJS连接MySQL报错 events.js:85 throw er; // Unhandled 'error' event Error: Connection lost:

时间:2021-11-26 00:09:03

       公司建了一个网站使用的sqlite+nodejs,最近考虑到把数据库换成MySQL,之前测试都还挺顺利的,后来就正式release到服务器上去了,突然间发现出现了后台崩掉,服务停止,一群老外都开始发邮件抱怨,不过起初都觉得是网络问题,没办法,*远程登陆到服务器重启服务,一段时间后又崩掉,其实只有我自己直到有bug,不敢跟老板啊别人讲~

       通过读后台的打印信息,如下:

events.js:85
      throw er; // Unhandled 'error' event
            ^
Error: Connection lost: The server closed the connection.
    at Protocol.end (/home/sanctuary/workspace/point_cloud_3/PointCloud/node_modules/mysql/lib/protocol/Protocol.js:113:13)
    at Socket.<anonymous> (/home/sanctuary/workspace/point_cloud_3/PointCloud/node_modules/mysql/lib/Connection.js:97:28)
    at Socket.<anonymous> (/home/sanctuary/workspace/point_cloud_3/PointCloud/node_modules/mysql/lib/Connection.js:502:10)
    at Socket.emit (events.js:129:20)
    at _stream_readable.js:908:16

    at process._tickCallback (node.js:355:11)

后来Google才知道MySQL数据库有一种机制就是node ***.js后默认8小时会自动关闭所有没有关闭的connection,因为我这个网站里面需要大量的查询,所以就将每一次查询就建立连接查询后关闭连接这种方法pass掉,当时也没有想太多,就觉得connection就让它一直保持,因为对这种机制的不熟悉所以才会有这种问题,

处理的方法就是:需要增加connection.on('error',function(err){

                                              if(err.code === 'PROTOCOL_CONNECTION_LOST') {
                                                     reconnection();
                                               }

                                        });

上面的代码在connection关闭时触发reconnection()函数,所有在reconnction()函数内在重新将以一个连接即可

function reconnection(){
        connection = mysql.createConnection({   
        host: "localhost",
        user: "root",
        password: "root",
        database:"logs"
       });
       connection.connect(function(err) {
       if(err){
           throw err;
           setTimeout('reconnection()', 1000);
       }
       });
       connection.on('error', function(err) {
            console.log(err);
            if(err.code === 'PROTOCOL_CONNECTION_LOST') {
                  reconnection();
            }
       });
}

这样的话每隔八小时数据库自动关闭连接的同时又重新建立了新的连接,后台程序不会崩掉了,

为了方便测试,可以登入到数据库,执行show global variables like 'wait_timeout';

mysql> show global variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 3600  |
+---------------+-------+
1 row in set (0.00 sec)

然后再执行set global wait_timeout=60;

mysql> set global wait_timeout=60;
Query OK, 0 rows affected (0.00 sec)
mysql> show global variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 60    |
+---------------+-------+
1 row in set (0.00 sec)

这样我们只需要等1分钟不必等待8小时就可以测试问题是否还会出现!当然时间数字可以自己设定进行测试,单位:秒

哎,心里的石头总算落地了!!