FastAPI - WSGI와 ASGI

Yoony·2023년 10월 30일
0

FastAPI 

목록 보기
1/1
post-thumbnail

FastAPI는 무엇인가?  

Python web framework

  1. 데이터 타입을 엔드포인트로 명시하지 않아도 된다. 
  2. Uvicorn ASGI Server를 사용한다. 
  • ASGI(Asynchronous Server Gateway Interface): 비동기 방식을 지원하는 웹 서버 
  • WSGI(Web Server Gateway Interface):웹소켓을 사용할 수 없고, HTTP/2 동시성을 적용할 수 없으며 파이썬 비동기를 사용할 수 없다는 한계가 있다. 

CGI와 FastCGI

외부 어플리케이션과 웹 서버(nginx, Apache 등)와 연결할 때 사용하는 인터페이스는 보통 CGI(Common Gateway Interface)를 사용합니다. CGI는 웹 서버와 외부 프로그램을 연결해주는 표준화된 프로토콜입니다. 

  • Web server: 웹 서버의 역항은 정적인 요청을 서빙하거나 Reverse Proxy를 이용하여 어플리케이션 서버로 동적인 요청을 전달하는 용도이다. 
  • CGI: 과거에는 정적 HTML 파일 하나를 가지고 웹 서비스를 했기 때문에 이러한 CGI가 필요하지 않았다. 하지만 웹에 대한 수요가 증가함에 따라 웹 서버가 처리할 수 없는 정보가 요청되었을 경우 그 처리를 외부 어플리케이션이 할 수 있도록 호출 함으로써 중계 역할을 한다.

그러나 CGI는 클라이언트의 요청이 발생할 때마다 프로세스를 추가로 생성하고 삭제하기를 반복한다. 이는 커널 리소스를 계속 생성/ 삭제하기 때문에 오버헤드가 심해지고, 성능 저하의 원인이 되기도 합니다. 

현대의 웹 서비스처럼 빈번하게 REST API가 호출 되고, 요청과 응답을 수시로 반복하여 처리하는 곳에서 이러한 아키텍처는 맞지 않는다. 그래서 생긴 것이 FastCGI 이다. 

FastCGI는 몇 번의 요청이 들어와도 하나의 프로세스만을 가지고 처리합니다. 즉 메모리에 하나의 프로그램만을 적재하여 계속 재활용하기 때문에 CGI에 비하여 오버헤드가 월등하게 감소한다. 

Java의 Tomcat 또한 Web Server + FastCGI를 채택한 형태로 다수의 사용자 접속에 유리하다. JVM 계열의 언어로 서버 프로그램을 작성하면 JBoss, Tomcat 등의 웹 어플리케이션 서버를 사용하는게 보편적이지만 이외에도 CGI를 수동으로 붙여서 사용할 수 있는 방법도 있었다.

그러나 Python에는 이러한 WAS가 별도로 존재하지않으며 결국 우리가 CGI, FastCGI 등을 이용해서 원하는 WAS 형태를 만들어서 사용해야 하는데, 실제로 Python만의 게이트웨이 인터페이스가 존재합니다.

WAS란?

"인터넷 상에서 HTTP 프로토콜을 통해 사용자 컴퓨터나 장치에 어플리케이션을 수행해주는 미들웨어로서, 주로 동적 서버 컨텐츠를 수행하는 것으로 웹 서버와 구별이 된다."

WAS는 웹 서버와 웹 컨테이너가 합쳐진 형태로, 웹 서버 단독으로는 처리할 수 없는 데이터베이스 조회나 다양한 로직 처리가 필요한 동적 컨텐츠를 제공한다. 덕분에 사용자의 다양한 요구에 맞춰 웹 서비스를 제공할 수 있다.

반면에 Web Server는 클라이언트(사용자)가 웹 브라우저에 어떠한 페이지 요청을 하면 웹 서버에서 그 요청을 받아 정적 컨텐츠를 제공하는 서버이다. 여기서 정적 컨텐츠란 단순 HTML 문서, CSS, Javascript, 이미지, 파일 등 즉시 응답 가능한 컨텐츠이다.

뿐만 아니라 웹 서버가 동적 컨텐츠를 요청 받으면 WAS에게 해당 요청을 넘겨주고, WAS에서 처리한 결과를 클라이언트(사용자)에게 서빙해주는 역할도 한다.

WAS 예: Tomcat
Web Server: Apache

그럼 WAS만 써도 될까? 답은 NO!

WAS는 DB 조회 및 다양한 로직을 처리하는 데 집중해야 한다. 따라서 단순한 정적 컨텐츠는 웹 서버에게 맡기며 기능을 분리시켜 서버 부하를 방지한다. 만약 WAS가 정적 컨텐츠 요청까지 처리하면, 부하가 커지고 동적 컨텐츠 처리가 지연되면서 수행 속도가 느려지고 이로 인해 페이지 노출 시간이 늘어나는 문제가 발생하여 효율성이 크게 떨어진다.

웹 서버를 WAS 앞에 두고 필요한 WAS들을 Web server에 플러그인 형태로 설정하면 더욱 효율적인 분산 처리가 가능하다.

근데 왜 Tomcat이 아닌 Apache Tomcat인가?

앞에서 언급한대로 정적 컨텐츠를 처리하는 웹 서버에는 Apache가 있고, 동적 컨텐츠를 처리하는 WAS 서버에는 Tomcat이 있는데 Tomcat은 Apache Tomcat이라는 이름으로 많이 사용되어 혼란스러울 것이다.

붙여서 쓰는 이유는 2008년에 릴리즈 된 Tomcat 5.5 버전부터 정적 컨텐츠를 처리하는 기능이 추가되었는데, 이 기능이 순수 Apache를 사용하는 것과 성능적 차이가 전혀 없으며 Tomcat이 Apache의 기능을 포함하고 있기 때문에 Apache Tomcat이라고 부르고있다.

WSGI

python 어플리케이션, 스크립트가 웹 서버와 통신하기 위한 인터페이스로써 CGI 디자인 패턴을 모태로 만들어졌으나 실제 CGI와는 다소 차이가 있다.

WSGI는 CGI와 동일하게 웹 서버와 애플리케이션 중간에 위치하는데, CGI와 다른점은 CGI는 매 요청마다 프로세스를 생성하고 WSGI는 한 프로세스에서 모든 요청을 받는다는 것입니다. 요약해서 CGI는 매 요청마다 커널 리소스를 추가/반납하고, WSGI는 많은 요청을 콜백으로 받아 처리하게 됩니다.

WSGI로 대표적인 두 가지 방법이 있습니다.

  1. nginx, apache에서 내장 모듈로 제공하는 server-often high profile 방식(ex. mode-wsgi, mod-python)

  2. Python 코드로 작성된 Web App server(ex. gunicorn)

결국 WSGI는 웹 서버와 애플리케이션 사이에 미들웨어 역할을 하며 기술적으로는 웹 서버, 애플리케이션 양쪽에서 WSGI에 대한 작동 코드가 필요한 Client-Server 모델을 응용한 것입니다. 웹 서버가 애플리케이션 코드를 직접적으로 읽을 수 없으므로 중간의 미들웨어가 해당 코드를 읽어서 반환해주는 방식입니다.

ASGI

WSGI만으로는 현대 웹 서비스의 대용량 트래픽 처리를 유연하게 하기가 어렵습니다. Python은 asyncio, coroutine과 같은 비동기 처리를 지원합니다. 그러나 WSGI는 동기 함수 처리만을 지원하여 여러 작업을 동시에 처리하는 것에 한계가 있습니다. 가령 현대 웹 서비스에는 웹 소켓 등을 사용한 실시간 채팅 서비스 등을 사용할 수도 있는데, WSGI로는 이러한 서비스를 구현하는 데 어려움이 있는 것이죠.

최근에는 Django 3.0 뿐만 아니라 FastAPI 등의 프레임워크에서도 ASGI를 적용하였습니다. WSGI와 다르게 요청을 비동기로 처리하며 Websocket 프로토콜과 HTTP 2.0을 지원합니다.

대표적인 ASGI Web app에는 uvicorn이 있습니다. uvicorn은 ASGI 기반의 웹 어플리케이션 서버로써 그 내장 모듈로 uvloop을 사용합니다.

_참고한 문서
1.https://blog.neonkid.xyz/249
2.https://velog.io/@crosstar1228/BackendFastAPI-%EC%9E%85%EB%AC%B8-1-Uvicorn-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-%EA%B0%84%EB%8B%A8%ED%95%9C-%EC%9B%B9-%EC%84%9C%EB%B2%84-%EA%B5%AC%ED%98%84

profile
Software Quality Engineer

0개의 댓글