Gunicorn이란?
Gunicorn(그린 유니콘, Green Unicorn)은 Unix 계열 운영체제에서 동작하는 파이썬용 WSGI HTTP 서버입니다. 루비(Ruby)의 Unicorn 프로젝트에서 영감을 받아 이식된 프로젝트로, “빠른 클라이언트와 게으른 애플리케이션을 위한” 서버라는 슬로건 그대로 단순한 구조와 가벼운 자원 사용, 폭넓은 프레임워크 호환성을 무기로 2010년부터 지금까지 파이썬 웹 서비스 배포의 사실상 표준으로 자리 잡고 있습니다.
프로젝트는 gunicorn.org와 GitHub – benoitc/gunicorn에서 관리되며, 이 글을 작성하는 시점 기준 GitHub 스타 1만 개, 포크 1,800개를 넘는 커뮤니티를 보유하고 있고 MIT 라이선스로 배포됩니다. 최신 안정 버전은 26.0.0이며, v25부터는 앱별 워커 할당(dirty arbiter)과 베타 단계의 HTTP/2 지원이 추가되는 등 꾸준히 발전하고 있습니다.
원래는 WSGI(Web Server Gateway Interface) 전용 서버로 시작했지만, 최근 버전에서는 asgi 워커 클래스를 통해 FastAPI, Starlette, Quart 같은 ASGI 기반 비동기 프레임워크도 직접 구동할 수 있게 되면서 활용 범위가 크게 넓어졌습니다.
핵심 특징
- Pre-fork 워커 모델: 아비터(Arbiter)라는 마스터 프로세스가 여러 개의 워커 프로세스를 미리 포크(fork)해 두고 요청을 분산 처리합니다. 아비터는 클라이언트 소켓을 직접 다루지 않고 워커 풀을 관리·감독하는 역할만 수행하기 때문에, 워커 하나가 죽어도 서비스 전체가 멈추지 않는 장애 격리 구조를 갖습니다.
- 다양한 워커 타입: 기본 sync 워커 외에도 스레드 풀 기반의 gthread, greenlet 기반의 gevent/eventlet, asyncio 네이티브 지원의 asgi, Tornado 전용 워커까지 워크로드 특성에 맞춰 선택할 수 있습니다.
- 광범위한 프레임워크 호환성: Django, Flask, Pyramid, Bottle 같은 전통적인 WSGI 프레임워크는 물론, FastAPI·Starlette·Quart 같은 ASGI 프레임워크까지 별도의 코드 수정 없이 그대로 구동합니다.
- 가벼운 설치와 최소한의 의존성: pip install gunicorn 한 줄로 설치가 끝나며, 컨테이너 환경부터 베어메탈 서버까지 어디서든 가볍게 동작합니다.
- 운영 편의 기능: TTIN/TTOU 시그널로 무중단으로 워커 수를 조절하고, HUP 시그널로 설정을 리로드하며, CHLD 시그널로 죽은 워커를 자동 재시작하는 등 프로덕션 운영에 필요한 기본기를 갖추고 있습니다.
- 프록시/로드밸런서 연동: Nginx, HAProxy 등과 함께 쓰는 것을 공식적으로 권장하며, PROXY 프로토콜(v1/v2) 지원, uWSGI 바이너리 프로토콜 지원 등 프런트 프록시와의 연동 기능도 폭넓게 갖추고 있습니다.
- HTTP/2 지원(베타): 최신 버전부터 멀티플렉싱 스트림을 활용하는 HTTP/2를 베타로 지원하기 시작했습니다.
설치와 기본 사용법
설치는 매우 간단합니다.
pip install gunicorn
가장 단순한 실행은 애플리케이션 모듈과 WSGI 콜러블 이름을 지정하는 것으로 끝납니다.
gunicorn myapp:app
기본값으로는 127.0.0.1:8000에서 서비스가 뜨며, 워커 개수는 다음과 같이 지정합니다.
gunicorn myapp:app --workers 4
FastAPI나 Starlette 같은 ASGI 애플리케이션은 워커 클래스를 asgi로 지정하거나, uvicorn의 워커 구현체를 명시적으로 지정해서 구동합니다.
gunicorn myapp:app --worker-class asgi
# 또는
gunicorn myapp:app -k uvicorn.workers.UvicornWorker --workers 4
워커 개수 산정 공식
공식 문서는 워커 수를 무작정 늘리기보다 CPU 코어 수를 기준으로 산정할 것을 권장합니다.
workers = (2 × CPU 코어 수) + 1
일반적으로 4~12개 정도의 워커면 트래픽이 많은 서비스도 충분히 감당할 수 있으며, 워커 수를 과도하게 늘리면 오히려 처리량이 떨어질 수 있다는 점도 함께 안내하고 있습니다.
워커 타입별 설정 예시
# 기본 sync 워커 – nginx 뒤에서 단순한 앱을 서비스할 때
gunicorn myapp:app
# gthread – keep-alive와 스레드 동시성이 필요할 때
gunicorn myapp:app -k gthread --workers 4 --threads 4
# gevent – I/O 바운드 앱의 대량 동시 접속 처리
gunicorn myapp:app -k gevent --workers 4 --worker-connections 1000
# ASGI – FastAPI/Starlette를 uvicorn 워커로 구동
gunicorn myapp:app -k uvicorn.workers.UvicornWorker --workers 4
스레드와 워커를 함께 조합할 수도 있는데, 스레드는 메모리를 공유해 자원 사용량이 낮은 대신 워커는 프로세스 단위로 격리되어 장애 대응력이 높다는 트레이드오프가 있습니다.
Nginx와 함께 배포하기
Gunicorn 공식 문서는 sync 워커를 쓸 경우 반드시 Nginx 같은 버퍼링 프록시 뒤에 배치할 것을 강조합니다. 그렇지 않으면 느린 클라이언트에 의한 서비스 거부(DoS) 공격에 취약해질 수 있기 때문입니다. 유닉스 소켓을 사용한 기본적인 연동 예시는 다음과 같습니다.
upstream app_server {
server unix:/tmp/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name example.com;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}systemd로 소켓 액티베이션을 구성하거나, Supervisor·runit 같은 프로세스 매니저와 조합해 무중단 재기동 체계를 갖추는 것도 실무에서 흔히 쓰이는 패턴입니다. 로그 로테이션은 SIGUSR1 시그널을 보내는 방식으로 처리합니다.
언제 async 워커를 써야 할까
공식 문서는 다음과 같은 경우에 sync 대신 gevent나 ASGI 워커를 검토하라고 안내한다.
- 외부 API, 느린 DB 호출처럼 오래 블로킹되는 작업이 많을 때입니다.
- 버퍼링 프록시 없이 인터넷 트래픽을 직접 받아야 할 때입니다.
- 스트리밍 요청/응답이나 롱폴링, 웹소켓을 다룰 때입니다.
아키텍처: Pre-fork 모델의 동작 원리
Gunicorn의 핵심은 아비터(Arbiter)와 워커 풀(Worker Pool)로 구성된 pre-fork 구조입니다.
- 아비터 프로세스가 시작되면서 설정된 개수만큼 워커 프로세스를 미리 포크합니다.
- 각 워커는 독립적으로 요청을 받아 처리하며, 워커 타입(sync/gthread/gevent/asgi/tornado)에 따라 동시성 처리 방식이 달라집니다.
- 아비터는 TTIN/TTOU로 워커 수를 실시간 조절하고, 워커가 비정상 종료되면 CHLD 시그널을 받아 자동으로 재시작하며, HUP으로 설정 리로드를 수행합니다.
이 구조 덕분에 하나의 요청 처리 중 예외가 발생해도 다른 워커나 아비터 자체에는 영향이 없다는 장점이 있습니다. 다만 sync 워커는 keep-alive를 지원하지 않고 요청마다 연결을 끊기 때문에, 반드시 프록시 뒤에서 운용해야 한다는 제약이 뒤따릅니다.
비슷한 파이썬 웹서버 라이브러리와 비교
Gunicorn은 파이썬 웹서버 생태계의 여러 선택지 중 하나입니다. 대표적인 대안들과 비교해보면 각자의 포지션이 뚜렷합니다.
uWSGI
C로 작성된 uWSGI는 Gunicorn보다 오래되고 훨씬 방대한 기능을 갖춘 애플리케이션 서버입니다. WSGI뿐 아니라 자체 프로토콜, 캐싱, 큐, 크론 등 다양한 부가 기능을 내장하고 있어 세밀한 튜닝이 가능하지만, 그만큼 설정 항목이 많고 학습 곡선이 가파르다는 평가를 받습니다. 반면 Gunicorn은 “합리적인 기본값”을 제공해 별다른 튜닝 없이도 바로 프로덕션에 투입할 수 있다는 점이 강점으로 꼽힙니다. 이미 uWSGI로 안정적으로 운영 중인 서비스라면 굳이 갈아탈 이유는 크지 않다는 것이 일반적인 실무 조언입니다.
Waitress
Waitress는 순수 파이썬으로 작성된 멀티스레드 기반 WSGI 서버로, HTTP 요청 버퍼링 같은 독자적인 안정성 기능을 갖추고 있습니다. Gunicorn이 프로세스를 포크하는 방식으로 CPU 코어를 적극 활용하는 데 비해, Waitress는 스레드 기반이라 I/O 바운드 소규모 애플리케이션에 적합하고 설정도 더 단순합니다. 다만 세밀한 설정 옵션이나 대규모 트래픽에서의 확장성은 Gunicorn에 비해 제한적입니다. 특히 Waitress는 Unix 전용이 아니라 Windows에서도 동작한다는 점이 Gunicorn과의 실질적인 차이입니다.
Uvicorn / Hypercorn (ASGI 서버)
Uvicorn은 FastAPI, Starlette 등 asyncio 기반 프레임워크를 위해 설계된 ASGI 서버로, 비동기 I/O와 웹소켓 처리에 최적화되어 있습니다. 문제는 Uvicorn 단독으로는 Gunicorn만큼 성숙한 다중 프로세스 관리, 워커 자동 재시작, 무중단 리로드 기능을 제공하지 않는다는 점입니다. 그래서 실무에서는 gunicorn -k uvicorn.workers.UvicornWorker처럼 Gunicorn을 프로세스 매니저로, Uvicorn을 실제 ASGI 실행 엔진으로 조합하는 구성이 널리 쓰입니다. HTTP/3나 QUIC, Trio 이벤트 루프까지 필요하다면 Hypercorn이 대안으로 거론되지만, 대부분의 서비스에는 과한 선택으로 평가됩니다.
관련 링크 : Uvicorn: 파이썬 ASGI 서버 라이브러리 완벽 가이드
Granian
Rust로 작성된 비교적 신생 서버인 Granian은 RSGI라는 자체 인터페이스를 통해 Gunicorn·Uvicorn 조합보다 낮은 요청당 오버헤드를 노립니다. 그러나 커뮤니티와 실제 프로덕션 사례가 아직 Gunicorn·Uvicorn만큼 축적되지 않았고, Rust/Python 경계를 넘나드는 디버깅이 까다로우며 일부 asyncio 의존 라이브러리와의 호환성 이슈도 보고됩니다. 실측으로 서버 자체가 병목임을 확인한 극소수의 경우가 아니라면, 굳이 먼저 도입할 이유는 크지 않다는 것이 최근 업계의 대체적인 평가입니다.
요약 비교표
| 항목 | Gunicorn | uWSGI | Waitress | Uvicorn |
| 구현 언어 | 순수 파이썬 | C | 순수 파이썬 | 파이썬(uvloop 등 C 확장 활용) |
| 프로토콜 | WSGI + ASGI(워커로) | WSGI, 자체 프로토콜 등 다수 | WSGI | ASGI |
| 동시성 모델 | pre-fork 멀티프로세스(+선택적 스레드/gevent) | 멀티프로세스 + 다양한 플러그인 | 멀티스레드 | asyncio 이벤트 루프 |
| 설정 난이도 | 낮음(합리적 기본값) | 높음(옵션이 매우 많음) | 낮음 | 낮음~중간 |
| 운영체제 | Unix 계열 | Unix 계열 | 크로스플랫폼(Windows 포함) | 크로스플랫폼 |
| 적합한 상황 | Django/Flask 등 전통 WSGI 서비스, 범용 프로덕션 배포 | 세밀한 튜닝이 필요한 대형 레거시 인프라 | 소규모 앱, 간단한 배포 | FastAPI 등 순수 async 앱(단, 보통 Gunicorn과 조합) |
장/단점
장점
- 간단한 진입 장벽: 설치 한 줄, 실행 한 줄로 서비스를 띄울 수 있고 기본 설정만으로도 프로덕션 품질에 근접합니다.
- 검증된 안정성: 2010년부터 운영되며 수많은 기업의 프로덕션 환경에서 검증된, 이른바 “battle-tested” 서버입니다.
- 유연한 워커 모델: CPU 바운드 앱은 sync/gthread로, I/O 바운드나 웹소켓은 gevent나 ASGI 워커로 워크로드 특성에 맞게 전환할 수 있습니다.
- WSGI와 ASGI 양쪽 지원: 레거시 Django 프로젝트부터 최신 FastAPI 서비스까지 하나의 도구로 아우를 수 있어 운영 표준화에 유리합니다.
- 운영 편의 기능 내장: 무중단 워커 스케일 조정, 설정 핫 리로드, 자동 워커 재시작 등 실무에 필요한 기능이 기본으로 들어 있습니다.
단점
- Unix 전용: Windows에서는 공식적으로 지원되지 않아, Windows 환경에서 개발·배포해야 한다면 Waitress 같은 대안을 검토해야 합니다.
- 단독으로는 프런트 서버 역할에 부적합: sync 워커는 keep-alive를 지원하지 않고 느린 클라이언트에 취약하기 때문에 Nginx 같은 리버스 프록시 없이 인터넷에 직접 노출하는 것은 권장되지 않습니다.
- 비동기 성능은 전용 ASGI 서버만 못할 수 있음: 순수 asyncio 성능 극대화가 목적이라면 Uvicorn/Hypercorn을 직접 쓰는 편이 오버헤드가 적을 수 있으며, Gunicorn은 그 위에서 프로세스 매니저 역할을 겸하는 조합으로 쓰이는 경우가 많습니다.
- uWSGI 대비 세밀한 튜닝 옵션은 상대적으로 적음: 매우 특수한 요구사항(커스텀 프로토콜, 세밀한 캐시/큐 통합 등)이 있는 대형 레거시 인프라에서는 uWSGI의 풍부한 기능이 아쉬울 수 있습니다.
정리
Gunicorn은 “빠르고 화려한 기능”보다 “예측 가능하고 안정적인 운영”에 초점을 맞춘 서버입니다. Django나 Flask 같은 전통적인 WSGI 애플리케이션을 배포한다면 여전히 가장 무난하고 검증된 선택이며, FastAPI 같은 ASGI 애플리케이션이라도 Uvicorn 워커를 얹어 Gunicorn을 프로세스 매니저로 쓰는 구성이 사실상 업계 표준으로 자리 잡았습니다. uWSGI만큼 세밀한 커스터마이징이 필요하거나, Uvicorn/Granian처럼 순수 비동기 처리량을 극한까지 끌어올려야 하는 특수한 상황이 아니라면, Gunicorn + Nginx 조합으로 시작하는 것이 여전히 가장 실패 확률이 낮은 선택입니다.






답글 남기기