서버를 실행했을 때 처음에는 잘 작동한다. 그러다 10분정도 뒤에 접속하게 되면 다음과 같이 서버에서 해당 API요청을 처리하지 못하는 상황이 발생한다.
어디가 문제인지 알기 위해서 Nginx, Gunicorn로그를 확인해보았다.
분명히 Guicorn log에 찍히는걸 보니 Flask서버까지 온다는 것은 확인했다.
그러면 DB에서 데이터를 불러오는게 문제인가 싶어 DB로그를 확인해보았다.
DB는 AWS RDS를 사용했기에 AWS홈페이지에서 확인했다.
Got timeout reading communication packets, Got an error reading communication packets 과 같은 에러가 뜨는 것을 보았다.
그렇다면 DB쪽에서 쿼리를 처리하지 못 해서 서버에서 API요청을 처리하지 못 한다는 것을 유추해 볼 수 있었다.
근데 DB에서 무엇이 문제이길래 이런걸까.. 해당 에러를 구글에 검색해보았다.
쿼리문이 너무 오래걸려서 DB에서 설정한 interactvie_timeout설정값을 넘어서서 그렇게 된다는 말이였다. 그래서 시간을 측정해보았다. 하지만 0.008초, 길어야 0.01초의 실행속도를 보여줬고 해당 말은 납득이 되지 않았다.
그래도 뭔가 timeout
이라는 문구가 보여 DB의 time설정부분과 어떻게 돌아가는지에 대해서 공부해보았다.
https://okky.kr/article/540700 그러다가 다음과 같은 글을 발견하게 되었다.
DB에 쿼리가 더 이상 날라가지 않아 연결이 끊어져 생기는 오류가 있다는 것이다.
이게 문제인가 싶어서 DB의 설정값을 확인했다.
show variables like 'wait_timeout';
wait_timeout
이라는 옵션은 활동하지 않는 커넥션을 끊을때까지 서버가 대기하는 시간을 말한다. 즉, 연결은 되어있지만 쿼리가 이 시간동안 날라오지 않는다면 끊어버린다는 얘기다.
28800이란 값이 들어있었다. 8시간뒤에 끊어버린다는 얘기인데 음.. 그러면 8시간동안은 멀쩡해야 하는거 아닌가.. 싶었다. 그건 나중에 더 공부를 해봐야겠다. 일단 해당 문제부터 해결해보자!
그래서 의미없는 쿼리를 날려 커넥션을 유지하는 방법을 찾아보았다.
Flask-SQLAlchemy에서 제공하는 pool_recycle
이라는 옵션이 있었다. DB에서 설정해둔 wait_timeout
이 지나 커넥션이 끊기기 전에 의미없는 쿼리를 날려 커넥션을 유지하는 것이다.
SQLALCHEMY_ENGINE_OPTIONS = {
'pool_recycle': 120
}
다음과 같이 설정하면 120초마다 DB의 쿼리를 날린다는 뜻이다.
주의사항으로는 DB에서 설정한 wait_timeout
보다는 작게 설정해놔야 의미가 있다는 것이다.
하여튼 이렇게 설정해두고 다시 배포를 진행해보았다. 이제는 오류가 뜨지 않았고 잘 작동하는 것을 확인했다..
한 3일정도는 이것때문에 고생이였다.. Nginx, Gunicorn설정등을 다 건드려보고 했는데 역시 로그보면서 하나하나 따라가다보면 답이 존재하는 것을 깨달았다.
참고
https://sjinstorage.blogspot.com/2019/11/got-timeout-reading-communication.html
https://yongho1037.tistory.com/569
https://pythonq.com/so/docker/1133414