티스토리 뷰

Node.js + forever module 로 백엔드 서버를 구축하여 돌리던 중,

Forever log 에 아래와 같은 메세지가 떳다.

 

Error: Connection lost: The server closed the connection.
    at Protocol.end (/home/ywlee/LifeCleanAPI/node_modules/mysql/lib/protocol/Protocol.js:112:13)
    at Socket.<anonymous> (/home/ywlee/LifeCleanAPI/node_modules/mysql/lib/Connection.js:97:28)
    at Socket.<anonymous> (/home/ywlee/LifeCleanAPI/node_modules/mysql/lib/Connection.js:525:10)
    at emitNone (events.js:91:20)
    at Socket.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)
error: Forever detected script exited with code: 1
error: Script restart attempt #1

왜??

 

google 에 검색해보면 stackOverFlow 에서 이 문제에 대한 질문들이 많이 올라와있다.

문제의 원인은 MySQL Database 를 사용하면서 DB timeout 과 관련된 문제였었다.

 

MySQL 의 타임아웃을 살펴보자

mysql> show variables like '%timeout%';
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| connect_timeout             | 10       |
| delayed_insert_timeout      | 300      |
| innodb_flush_log_at_timeout | 1        |
| innodb_lock_wait_timeout    | 50       |
| innodb_rollback_on_timeout  | OFF      |
| interactive_timeout         | 28800    |
| lock_wait_timeout           | 31536000 |
| net_read_timeout            | 30       |
| net_write_timeout           | 60       |
| rpl_stop_slave_timeout      | 31536000 |
| slave_net_timeout           | 3600     |
| wait_timeout                | 28800    |
+-----------------------------+----------+
12 rows in set (0.00 sec)

이중 우리가 봐야 할 것은 

 - interactive_timeout : 활동중인 커넥션이 닫히기 전까지 서버가 대기하는 시간

 - wait_timeout : 활동하지 않는 커넥션을 서버가 끊기까지 대기하는 시간

 

위 변수대로 살펴보면

 - interactive_timeout = 28,800 초 (8시간)

 - wait_timeout = 28,800 초 (8시간)

 

즉, Client 의 마지막 활동 후 서버는 interactive_timeout인 8시간 동안 기다리고, 

8시간동안 기다린 후, wait_timeout 인 8시간동안 추가로 기다린 후 연결을 끊는다는 것으로 보인다.

(제 추측입니다. 혹시 틀리다면 댓글로 피드백 부탁드립니다.)

 

즉, 이 시간동안 클라이언트가 아무런 동작도 없으면 Mysql 데몬은 연결을 끊어버리는데, 

이때 Node.js 서버에서 Error Exception 핸들링이 되어있지 않으면 서버가 죽는 것으로 보입니다.

 

애초에 백엔드 서버가 거의 16시간이나 client 요청이 없다는건 슬픈일이다..ㅠㅠ

내 서버가 그렇지 ㅠㅠ...


해결

여러가지 해결 방법이 있다.

 

solve 1) MySQL Timeout 변수 조정

mysql> set interactive_timeout={원하는 타임아웃 시간};
mysql> set wait_timeout={원하는 타임아웃 시간};

 

solve 2) 에러 핸들링

Stack Over Flow 에서 얻은 에러 핸들링이다.

에러가 나서 핸들링되면, 다시 연결을 요청하는 것으로 보인다.

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();

 

solve 3) Request 보내기

timeout 시간이 되기전 Client 에서 Server 로 주기적으로 Request 를 날려 서버가 죽지 않게 하는 방법이다.

뭐..어렵진 않지만.. 이것도 사실 에러에 대한 근본적인 해결책은 아님.

 

solve 4) forever 로 서버를 돌리니까 신경 안쓰기

모든 것이 귀찮으신 분들은 forever 모듈이 어차피 서버가 죽으면 되살려주니..

forever start [노드서버] 로 서버를 돌려 신경안쓰고 있으면 됨....(근데 찝찝)

 

 

 

 

 

 

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함