1. Gunicorn 이란?
• WSGI 서버 중 하나 (Python 웹앱 배포에 자주 사용)
• 비동기 프레임워크가 아닌 WSGI 앱(Django, Flask 등)과 함께 사용
• Pre-fork 모델 기반으로 작동
2. Gunicorn 구조
flowchart TD
A[Client Request] --> B[Gunicorn Master Process]
B --> C1[Worker Process 1]
B --> C2[Worker Process 2]
B --> C3[Worker Process 3]
B --> Cn[Worker Process N]
C1 --> D[flask/Django]
C2 --> D
C3 --> D
Cn --> D
D --> E[Response to Client]
- worker: 클라이언트 요청을 실제로 처리하는 하위 프로세스
- Gunicorn은 메인 프로세스가 요청을 받아 worker에게 분배
3. Worker 종류
| Worker 종류 |
인터페이스 |
특징 |
| sync |
WSGI |
기본 동기 worker |
| gevent, eventlet |
WSGI |
비동기 worker, greenlet 사용 |
| tornado |
WSGI |
Tornado 프레임워크 전용 |
| uvicorn.workers.UvicornWorker |
ASGI |
비동기 프레임워크용 (FastAPI 등) |
- 현재 서버에서 사용 가능한 워커는
- sync, gevent, eventlet
- sync는 동기적으로 처리
- gevent. greenlet은 동시성 처리 가능
- 동기, 비동기
- 동기: 앞 작업이 끝날때까지 다른 작업을 시작하지 않음
- 비동기: 작업을 중간에 멈추고 다른 작업을 동시에 진행할 수 있음
- 동시성, 병렬성
- 동시성: CPU 1개가 다른 디바이스 or 네트워크를 기다리는 동안, 다른 작업을 진행할 수 있는지?
- 병렬성: 물리적으로 실제로 2개의 작업이 진행되는지? CPU가 2개 이상이어야함
- 병렬성은 실제로는 동시성은 아니지만 동시성처럼 보일 수 있음
- 동시에 여러작업을 진행하는 것처럼 보여서 계속 헷갈림?
- 동시성/병렬성, 동기/비동기
- 동기적으로는 동시성이 안됨
- 동시성을 만족하기 위해선 비동기 동작을 만족 할 수 있어야함
gevent 워커 동작 방식
왜 경량 스레드는 OS 스레드 보다 가볍지?
- 유저 모드 → 커널 모드 전환 으로 인한 인터럽트
- 전체 레지스터, 커널 스택 저장 필요
- 캐시 손실
- 스케줄러 오버헤드
Gevent에서 greenlet을 쓰는 방식
동작 방식
- gevent는 libev(이벤트 루프)를 통해 greenlet들을 감시하고, 준비된 greenlet들을 실행함
import gevent
def task():
print("running")
g = gevent.spawn(task) # 내부적으로 Greenlet 생성
monkey.patch_all()
def fetch():
s = socket.socket()
s.connect(('example.com', 80))
s.send(b"GET / HTTP/1.0\r\n\r\n")
print(s.recv(1024)) # 비동기처럼 보이지만...
gevent.spawn(fetch)
- recv()이 내부적으로 I/O Watcher에 등록됨
- 블로킹 발생 시 → 현재 greenlet의 컨텍스트 저장 → Hub로 전환 -> 다른 스레드 실행
- 이벤트 감지 시 → 다시 해당 greenlet으로 switch()
monkey patch?
- 파이썬 기본 라이브러리가 블로킹 방식으로 동작해서, 동시성을 보장하기위해 monkey 패칭
- 예시
- socket.socket → gevent.socket.socket
- time.sleep → gevent.sleep
- ssl → gevent.ssl
gevent와 eventlet 차이
- Python의 Green Thread 기반 동시성 라이브러리
- 내부적으로 greenlet 사용
- gevent와 비슷하지만, 구현 방식과 일부 API는 다름
| 항목 |
gevent |
eventlet |
| 이벤트 루프 |
libev 사용 (C 빠름) |
순수 Python |
| 성능 |
빠름 |
상대적으로 느림 |
| I/O 감시 |
libev |
select/poll/epoll 등 |
| 코드 베이스 |
C + Python |
거의 Python |
| 안정성 |
더 널리 쓰임 (Flask, Requests 등과 호환성 높음) |
간단하고 순수 파이썬 기반 |
참고
greenlet의 동작 방식
동시성 구현 5가지 종류(자원관리, 서버 아키텍쳐 관점)