내 웹사이트가 문제없이 항상 잘 작동되고 있는 줄 알았다.
매번 deploy 작업 직후 잘 동작하는지 체크해보면 빠릿빠릿 잘 돌아가길래
'음 잘 되네' 하고 뿌듯해하며 내버려뒀음.
근데 내가 안 볼 때면 심심할 때마다 네트워크 에러를 띄운다는 사실을 며칠 전에 알게 됨.
콘솔을 확인해보니 "Access to XMLHttpRequest has been blocked by CORS policy"에
"Error: Request failed with status code 503" 어쩌구가 시뻘겋게 떠있었음 🤬
그렇게 CORS 에러를 해결하기 위해 밤을 지새웠다...
여러 해결 방법들을 적용해봐도 deploy 직후에는 잘 되는듯 했으나,
몇분만 지나면 갑자기
2022-03-20T13:02:52.922283+00:00 app[web.1]: /app/node_modules/newrelic/lib/shim/shim.js:1320
2022-03-20T13:02:52.922294+00:00 app[web.1]: throw error // Re-throwing application error, this is not an agent error.
2022-03-20T13:02:52.922295+00:00 app[web.1]: ^
2022-03-20T13:02:52.922296+00:00 app[web.1]:
2022-03-20T13:02:52.922296+00:00 app[web.1]: Error: Connection lost: The server closed the connection.
2022-03-20T13:02:52.922297+00:00 app[web.1]: at Protocol.end (/app/node_modules/mysql/lib/protocol/Protocol.js:112:13)
2022-03-20T13:02:52.922297+00:00 app[web.1]: at Socket.<anonymous> (/app/node_modules/mysql/lib/Connection.js:94:28)
2022-03-20T13:02:52.922298+00:00 app[web.1]: at Socket.<anonymous> (/app/node_modules/mysql/lib/Connection.js:526:10)
2022-03-20T13:02:52.922299+00:00 app[web.1]: at Socket.emit (node:events:538:35)
2022-03-20T13:02:52.922299+00:00 app[web.1]: at /app/node_modules/newrelic/lib/shim/shim.js:1314:22
2022-03-20T13:02:52.922300+00:00 app[web.1]: at LegacyContextManager.runInContext (/app/node_modules/newrelic/lib/context-manager/legacy-context-manager.js:59:23)
2022-03-20T13:02:52.922300+00:00 app[web.1]: at Shim.applySegment (/app/node_modules/newrelic/lib/shim/shim.js:1304:25)
2022-03-20T13:02:52.922301+00:00 app[web.1]: at Socket.wrapper (/app/node_modules/newrelic/lib/shim/shim.js:1916:17)
2022-03-20T13:02:52.922301+00:00 app[web.1]: at /app/node_modules/newrelic/lib/shim/shim.js:1314:22
2022-03-20T13:02:52.922301+00:00 app[web.1]: at LegacyContextManager.runInContext (/app/node_modules/newrelic/lib/context-manager/legacy-context-manager.js:59:23)
2022-03-20T13:02:52.922302+00:00 app[web.1]: Emitted 'error' event on Connection instance at:
2022-03-20T13:02:52.922303+00:00 app[web.1]: at Connection._handleProtocolError (/app/node_modules/mysql/lib/Connection.js:423:8)
2022-03-20T13:02:52.922303+00:00 app[web.1]: at Protocol.emit (node:events:526:28)
2022-03-20T13:02:52.922303+00:00 app[web.1]: at Protocol._delegateError (/app/node_modules/mysql/lib/protocol/Protocol.js:398:10)
2022-03-20T13:02:52.922304+00:00 app[web.1]: at Protocol.end (/app/node_modules/mysql/lib/protocol/Protocol.js:116:8)
2022-03-20T13:02:52.922304+00:00 app[web.1]: at Socket.<anonymous> (/app/node_modules/mysql/lib/Connection.js:94:28)
2022-03-20T13:02:52.922304+00:00 app[web.1]: at Shim.applySegment (/app/node_modules/newrelic/lib/shim/shim.js:1304:25) {
2022-03-20T13:02:52.922305+00:00 app[web.1]: fatal: true,
2022-03-20T13:02:52.922305+00:00 app[web.1]: code: 'PROTOCOL_CONNECTION_LOST'
2022-03-20T13:02:52.922305+00:00 app[web.1]: }
2022-03-20T13:02:53.100632+00:00 heroku[web.1]: Process exited with status 1
2022-03-20T13:02:53.167497+00:00 heroku[web.1]: State changed from up to crashed
2022-03-20T13:09:27.609089+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=OPTIONS path=...
뭐 이런 에러가 나면서 웹사이트의 기능들이 제 기능을 못 했다.
계속 삽질을 하다가 결국 딴데서 원인이 있었음을 알아냄.
✅ Solution
초반에 설정해놓았던 CORS options의 문제가 아니었다.
알고보니 ClearDB와의 접속이 자꾸 끊어져서 생긴 문제였던 것.
생각치도 못했던 원인 ㄴㅇㄱ
DB connection 설정하는 코드에서
// 기존 코드
mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
charset: "utf8mb4",
});
createConnection ➡ createPool
// 수정된 코드
mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
charset: "utf8mb4",
});
이렇게 바꿔줬더니 바로 해결됐다!!
createConnection과 createPool의 차이점이 뭐길래?
궁극적인 목적은 DB connection을 만드려는 것으로 동일하다. 동작 방식이 다를뿐.
createConnection : connection을 한 번 생성하면 커넥션을 직접 종료하거나, mysql 서버가 커넥션을 끊을 때까지 그 하나의 커넥션만 존재. 그 커넥션을 다른 곳에서 참조할 수도, 재사용할 수도 있음.
createPool : 여러 connection들이 저장되는 공간. 이 pool에 커넥션을 요청하면 아무도 쓰고 있지 않아 놀고 있는(?) 상태의 커넥션을 받는다. 요청한 시점에 pool에 놀고 있는 커넥션이 아예 없다면 새로 생성된 커넥션을 받게 된다. 새로운 커넥션 생성을 더 이상 할 수 없는 지경에 다다르면, 기존의 것들 중 사용 가능한 상태의 커넥션이 생길 때까지 기다려야한다. 이 커넥션들은 open된 상태로 유지 가능하며, 쉽게 재사용이 가능하다.
⬆ 제가 직접 번역했는데 아무래도 좀 어설프네요...
참고자료에 첨부한 원문을 읽으시면 확실하게 이해되실겁니다 ㅜㅜ
한 줄만 바꿔줬을 뿐인데 지긋지긋했던 CORS 관련된 문제가 더는 안 생기고,
heroku logs에 App crashed라면서 뜨던 에러 로그도 더 이상 안 보이니 신기하다 ㅎㅎ
참고자료
❤와 댓글은 큰 힘이 됩니다. 감사합니다 :-)
'Devlog > Web' 카테고리의 다른 글
Heroku 배포 - 백엔드 배포 과정 중 나를 당혹스럽게 만들었던 상황 모음집 (4) | 2022.03.18 |
---|---|
[SQL] Basic SQL Statements (0) | 2022.03.02 |
Netlify 배포 - 빌드 에러 해결방법 (0) | 2022.02.28 |
[Express+MySQL] DB 연결 시 발생하는 access error 해결방법 (0) | 2021.11.23 |
[React] hover effect 이벤트함수가 child element에 제대로 적용이 안 될 때 해결방법 (2) | 2021.10.11 |