Codong's Development Diary RSS 태그 관리 글쓰기 방명록
서버, 네트워크 (1)
2021-03-22 22:18:15

😫 개요


nginx + gunicorn + flask 조합으로 배포를 해봤었다. supervisor로 모니터링하고 로그를 관리하고 있었다. 그런데 문제는 내가 배포한 플라스크의 모델이 돌아가는데 시간이 길면 1~2분 소모되다보니, 결과값이 나오지 않고 도중에 끊기는 것이다..? 후.. 로컬에선 잘만 돌아가던데.. 🤯 화난 마음을 가라 앉히고, 이럴땐 로그부터 하나씩 살펴보자!

➕ 혹시 supervisor에 더 알고 싶으면 이곳을 참고하자.


🧐 문제 해결 시도


1️⃣ Nginx 로그 확인

제일 먼저 nginx의 err log를 살펴봤다.

# nginx err.log
2021/03/22 20:54:30 [error] 21863#21863: \*335 upstream prematurely closed connection while reading response header from upstream

이 에러가 뜨면서 되지가 않는 것이다. 대강 파파고를 돌려보면 '업스트림에서 응답 헤더를 읽는 동안 업스트림 연결이 조기에 닫힘'이라는데 대충 뭔가 timeout 같다는 느낌이 온다. 그래서 nginx문제인가 싶어서 설정파일에서 아래 부분을 추가했다.

# /etc/nginx/site-enabled/default

...

client_max_body_size 300M;
client_header_timeout 300;
client_body_timeout 300;

...

location / {

    proxy_read_timeout 300s;
    proxy_connect_timeout 300s;

    ...

    }

client_max_body_size는 혹시 몰라서 늘려봤는데, 생각해보니 플라스크 로직 내에서만 큰 용량을 차지하는데, 상관없던 것 같다.
이렇게 설정 파일을 수정한 후에는 꼭 sudo service nginx restart 를 해서 수정한 부분을 적용시켜주자

하지만 여전히 똑같은 현상이 발생하고 있었다... ㅂㄷㅂㄷ 🤬


2️⃣ flask 출력 로그 확인

진짜 뭐지 싶어서 있는 로그가 뭐가 있을까 하다가, 플라스크 실행 로그가 떠올라서 확인해보기로 했다.

# stdout.log
[2021-03-22 20:54:30 +0900] [22129] [CRITICAL] WORKER TIMEOUT (pid:22160)

잡았다 요놈.... 결국 gunicorn의 워커가 timeout이 발생한 것이다. 공식문서에 따르면 default 값으론 30초 였다.
30초론 택도 없지... 길때는 2분까지 걸리는 플라스크에서 돌아가는 연산을 감안하면 이 문제 때문이라고 생각이 된다.

난 supervisor를 이용하니까 .conf에서 세팅을 다시해줬다.

# /etc/supervisor/conf.d/<프로젝트이름>.conf
...
command=<가상환경경로>/gunicorn -b 127.0.0.1:5000 -w 2 -t 240 run:app --preload
...

여기서 -t 240 를 통해 Timeout을 240초로 설정해주는 커맨드다.
자 이제 모든 것이 끝났으니, 적용시켜보자.

sudo supervisorctl restart <program명> 이렇게 해주면 끝인데............. 이걸로만 될 줄 알았는데 .........

여기서 부터 나의 악몽이 시작됐다..😱


3️⃣ 적용이 안되는 삽질

분명 로직상 안될 것이 없는데 계속 똑같은 에러가 발생하는 것이다.


진짜 내가 설정을 잘못했나 싶어서 구글링 엄청하면서 비슷해보이는 코드 적용시켜보고 순서도 바꿔보고, 등등 2시간을 그렇게 삽질했다. 진짜 안되길래 화가나서 worker 수를 바꿔보고 로그 찍어보니 바뀌지가 않는 것이다..? 그래서 로컬에서 돌려보니 로컬에선 되는데 왜 supervisor를 이용하면 안될까? 라는 생각을 하다가 원인을 알아냈다.


그냥 설정 파일의 수정 사항이 적용이 안되는 것이었다.

그래서 supervisor를 reload 해봤다.... 결과는.... 너무 잘되는 걸 😭 (내 2시간..)
sudo supervisorctl reload <program명>


결론 : 여러분들 supervisor .conf 파일 수정후 reload 꼭 하세요... 두 번 하세요 아니 세 번...


🥱 마무리


그래도 이번 경험을 통해 nginx나, gunicorn이 뭔지 살짝 더 알게 되었다. 그리고 꼭 아는 명령어를 맹신하지 말아야겠다는 생각을 가졌다. restart와 같이 정확하게 알지 못하면서 되겠지 라고 생각하기 보다 정확한 쓰임을 알고 사용할 수 있도록 노력해야겠다.