Python ASGI 배포 서버
Python에서 웹 어플리케이션(Django, FastAPI, Flask 등)을 배포시 비동기 요청 처리를 위해, ASGI 서버를 사용하여 배포하게 되는데, Python 기반의 ASGI 서버들을 비교해보며, 종류와 특징에 대해 알아 본다.
주로 많이 언급되는 건 다음과 같다.
- Uvicorn (asyncio, uvloop)
- Daphne
- Hypercorn
- Starlette
사실 결론부터 말하자면, 사용하는 프레임워크나 기능에 따라 배포 서버에 대한 선택지가 한정적인 것으로 생각되는데
FastAPI로 배포를 희망
→ 공식문서에서 지원하는 Uvicorn이나 Hypercorn 을 쓰는 것이 일반적
Django / Flask 에 Websocket 프로토콜 처리가 필요
→ Daphne 이 적절
Starlette
→ ASGI 서버 보다는, 프레임워크의 기본 기능들을 제공해주는 툴킷임.
Uvicorn
링크 : uvicorn 공식 문서 링크
정의
- 파이썬 전용 ASGI (Asynchronous Server Gateway Interface) 서버
- uvloop (이벤트 loop, c기반) + httptools (http 프로토콜 처리) 조합을 이용해 ASGI를 구현함
특징
- 주로 FastAPI / Django Ninja 등과 함께 사용
- uvicorn 은 단일 프로세스로 동작
- 파이썬 언어에 내장된 asyncio의 이벤트 루프 역할을 → uvloop로 대체하여 더 빠르게 동작
설치 방법
# cpython 기반 dependency 설치 <- 권장
pip install uvicorn[standard]
# event loop로 asyncio 사용
pip install uvicorn
배포
- FastAPI + Gunicorn + Uvicorn (worker) 조합 으로 많이 사용
Q & A
Q.1 Uvicorn을 단독적으로 쓰지 않고, Gunicorn에 붙여 쓰는 이유는?
uvicorn 은 단일 프로세스로 멀티 스레딩을 통해 동작
일정 트래픽 이상 넘어 서면, 단일 프로세스에서 스레드를 통한 작업의 한계가 존재
웹 어플리케이션을 프로세스 레벨(worker)로서 관리해주는 Gunicorn에 uvicorn 각각을 worker로 붙여 배포
즉 Gunicorn이 ASGI 요청을 처리하는 Uvicorn을 Worker로 여러개로 만들어 더 많은 요청을 분산/관리해주며 보완 목적
Q.2 왜 비동기 방식인 Uvicorn에 한계가 존재하는가?
물론, 단일 프로세스 만으로도 높은 동시성 성능을 확보가 가능하지만, 주된 latency는 스레드의 공유 자원에 대한 병목에서 발생한다. (공유 자원을 기다리는 상황)\
Asyncio
- Asyncio는 Python 3.5 버전 부터 내장 된 비동기 I/O 라이브러리
- async / await 구문을 사용하여 비동기(Asynchronous) 코드 작성 가능
- non-blocking 한 상황(API 작동시 대기 시간이 긴 경우에도 CPU가 다른 처리를 할 수 있는 상황)을 만듬
uvloop
- NodeJS V8 엔진에서 사용하는 libuv(고성능 다중 플랫폼 비동기 I/O 라이브러리) 기반
- asyncio를 대체하기 위해 만들어졌으며, 실제 성능상 uvloop+httptools의 성능은 Go 프로그램의 성능과 비슷
Daphne
링크 : daphne 공식 github 링크
정의
- Django Channels를 지원하기 위해 개발된 ASGI 서버
- Django/Flask 에서 WSGI 요청과, ASGI 요청을 Channels 개념을 통해 처리
특징
- HTTP, HTTP2, WS 프로토콜 처리를 지원
- HTTP, WS 요청을 Daphne를 통해 수신 이후 Channels는 두 프로토콜을 구분하여 처리
- 주로 채팅 시스템과 같은 websocket 이용한 개발시 많이 사용되는 것으로 보임
Daphne - Channels 적용 전/후 구조 비교
- HTTP 프로토콜은 Views로, Websocket 프로토콜은 Consumers로 둘을 분리하여 처리
- 이러한 처리를 해주는 것 Channel Layer
Hypercorn
정의
- Python 3.6 이상의 버전에서 사용되는 ASGI 서버
특징
- 프로토콜 지원을 강조하여 HTTP/1, HTTP/2 및 HTTP/3을 지원 (HTTP/3 은 추가 라이브러리 필요)
- (추가) sans-io (네트워크 I/O Free)를 기반 (이부분은 잘 모르겠음)
- asyncio와 uvloop를 기반으로 하여 빠른 속도와 고성능 제공
- Hypercorn은 작고 가벼워, 배포 및 확장이 쉬움
Starlette
링크 : starlette 공식 문서 링크
정의
- Python 3.6 이상의 ASGI 프레임워크(애플리케이션)를 위한 툴킷 (ASGI 서버 보다는 툴킷이 주목표)
특징
- FastAPI이 해당 Starlette 기반으로 작성되었으며, 모듈성이 매우 좋음
- starlette은 ASGI 프레임워크끼리 공통적으로 사용 할 수 있는 기능(ex. --reload 옵션 등)의 모듈화를 목표함
- starlette을 마운트 한 ASGI 프레임워크들 끼리는 starlette의 주요 기본 기능들을 이어 받아, 애플리케이션 구현 방식이 프레임워크 간 통일성이 생김
툴킷으로서의 Starlette 주요 기능
- 가볍고, 복잡도가 낮은 HTTP Web Framework
- 프레임워크 인-프로세스 Background 작업
- 시스템 start-up, shut-down 이벤트
- WebSocket, Streaming 관련 지원
- CORS, GZip 등
- 세션 및 쿠키
- 코드 Annotation (타입 hinting)
참고 문헌
- https://hidekuma.github.io/python/uvloop/ : Python: asyncio를 더 빠르게 만드는 uvloop 살펴보기
- https://weekwith.tistory.com/entry/Starlette-%EC%86%8C%EA%B0%9C : starlette 소개
'Python > Deployment' 카테고리의 다른 글
[배포] Python WSGI 배포 서버 종류 (Gunicorn, uWSGI) (0) | 2023.07.08 |
---|---|
[웹서버] WebServer와 WAS 차이 (0) | 2022.08.23 |
[배포] CGI vs ASGI vs WSGI 비교 (0) | 2022.07.15 |