운영중인 장고 + 지유니콘 백엔드 메모리 누수 문제 해결 production django + gunicorn backend memory leak fix (feat uwsgi)

JIHUN KIM
4 min readNov 4, 2019

필자는 회사에서 django+gunicorn 스택으로 백앤드를 다루고 있다.
이전에는 django+uwsgi를 사용하였으나, 메모리를 구글 크롬 브라우저급으로 먹어대는 uwsgi 녀석을 더이상 사용하지않고… gunicorn으로 서비스를 운영하기 시작했다.(전글 python개발자 uwsgi를 버리고 gunicorn으로 갈아타다)

꾸준하게 올라가고 있는… 메모리 사용량….10월 30일 배포(release) 이후 쭉쭉 증가하고 있었다..메모리누수이다.

팀의 동료로부터 django+gunicorn 백앤드 서비스의 memory 사용량이 시간이 지남에따라 점점 늘고 있다고 전달을 받았고, 관리자 툴을 이용해서 확인해본 결과 위와 같은 그래프의 모양으로 메모리가 점점 증가 하고 있다는 것을 확인했다.

짐작으로는 django + gunicorn + supervisor로 사용을 하고 있는데
gunicorn 설정중에서 max-requests가 세팅이 되어있지 않았고 그로인해서 메모리 누수가 발생했을 것이라 예상하였다.
(max-request설정을 해주지 않는다면 worker가 리스타트를 하지않는 문제가 발생한다)

점진적으로 증가하는 메모리 누수 현상을 확인 할수있다.

Gunicorn 에서는 max-requests라는 기능을 제공한다.
명시적으로 특정 requests만큼의 요청을 받은 후 worker가 자연스럽게 restart를 해주는 기능이다. 이 기능을 통해서 worker가 물고있던(?) 메모리를 릴리즈해주게된다. 또 max-requests-jitter이라는 기능이 있는데, 모든 worker가 restart 가 되어 다운타임이 상황이 발생장애로 이어질수가 있는데 jitter라는 명령어로 이 상황을 회피할 수 있다.

## supervisor.conf 또는 gunicorn 배포 스크립트에 아래와같이 추가를 해준다.
gunicorn --max-requests 1000 --max-requests-jitter 50 ... myapp.wsgi
코드 변경후 배포 시점 비교
before ( — max-requests 설정 전)
after ( — max-requests 설정 후)

메모리 사용량이 조금씩 조금씩 점진적으로 증가하고있던 녹색 면적에 비해서 수정 배포후 달라진 모습을 볼 수 있다. ( 뭔가 메모리 사용량이 급증하는 것 처럼보이나 몇분 후에 다시 제자리로 돌아오는 모습을 확인 할 수 있었다.

딱 두개면 된다!

uwsgi도 비슷한 방법으로 max-requests를 설정하거나 max-requests-delta를 설정하여 메모리 누수를 방지할수 있다.
하지만 필자는 uwsgi를 사용하는 것을 권장하지않는다.

참조: https://adamj.eu/tech/2019/09/19/working-around-memory-leaks-in-your-django-app/

--

--

JIHUN KIM

개발자를위한 교육플랫폼 알프캠퍼스를 만들고있습니다! https://github.com/leopard627