WSGI로 보는 웹 서버의 개념

Web server, WSGI, Middleware, Application

예전에 웹 서버와 WAS, WSGI를 공부하면서 블로그에 포스팅을 몇 개 한 적이 있는데, 이제서야 개념정리가 좀 되어 한 글에 정리하기로 했다.

웹 서버

khanrc: 웹서버, WAS, CGI
웹 서버는 정적이다. 리퀘스트가 들어오면 그 리퀘스트를 분석하여 알맞는 리소스를 리턴한다.

이 웹서버를 동적으로 기능하게 하기 위해서 웹서버 위에 flask, django, rails, node.js따위의 프레임워크를 얹는다. 그게 바로 WAS 다.

웹서버의 구조

apache라고 하자.

  1. 80번 포트를 listening
  2. 리퀘스트가 들어오면 리퀘스트를 처리하기 위한 apache process를 fork
  3. 포크된 아파치 프로세스는 리퀘스트에 붙어 처리하고 원래 있던 프로세스는 그대로 listen

이게 과거의 아파치다. 문제는, 프로세스는 무겁다. nginx는 이를 쓰레드로 전환하여 속도를 향상시켰다. 지금은 아파치도 쓰레드 형태로 전환하여 비슷한 퍼포먼스가 나온다고 한다.

프로세스: code, data, heap, stack 모두 갖고 있는 하나의 덩어리. 즉 독자적인 메모리를 갖고 있다.
쓰레드: 라이트웨이트 프로세스. 하나의 프로세스 안에서 code, data, heap을 공유하고 stack만을 별도로 가지고 있다. 즉 메모리를 공유한다.

WAS

웹 서버 위에 서버 어플리케이션을 얹은 것이 바로 WAS.

WSGI

khanrc: WSGI와 CGI의 차이
ko.wiki: WSGI
Web Server Gateway Interface. 파이썬에서 어플리케이션, 즉 파이썬 스크립트가 웹 서버와 통신하기 위한 명세다. 프로토콜 개념으로 이해하면 될 듯.

WSGI는 서버와 앱 양단으로 나뉘어져 있다. WSGI 리퀘스트를 처리하려면 서버에서 환경정보와 콜백함수를 앱에 제공해야 한다. 앱은 그 요청을 처리하고 콜백함수를 통해 서버에 응답한다.

Middleware

이러한 커뮤니케이션을 WSGI 미들웨어가 보충한다. 이 미들웨어는 서버의 관점에서는 앱으로, 앱의 관점에서는 서버로 행동한다. 이 미들웨어는 아래와 같은 기능을 가진다.

  • 환경변수가 바뀌면 타겟 URL에 따라서 리퀘스트의 경로를 지정해준다.
  • 같은 프로세스에서 여러 애플리케이션과 프레임워크가 실행되게 한다.
  • XSLT 스타일시트를 적용하는 것과 같이 전처리를 한다.

미들웨어에는 mod_wsgi, uwsgi, gunicorn, twisted.web, tornado 등등이 있다.

어플리케이션의 관점에서는 이 미들웨어를 통해 앱이 실행되므로 앱을 실행시켜주는 어플리케이션 컨테이너(Application Container)라고도 할 수 있다.

Framework

서버 어플리케이션을 만들기 위해 사용하는 최상단 웹 프레임워크. Flask로 대표되는 Micro 프레임워크와 Django로 대표되는 Full-stack 프레임워크로 나눌 수 있다.

spoqa tech blog: Flask로 만들어 보는 WSGI 어플리케이션

종합

  1. http 리퀘스트가 들어오면
  2. 웹 서버가 그 리퀘스트를 받고
    • 서버사이드 처리가 필요 없으면 리스폰스를 리턴(static한 웹 서버)
  3. 서버사이드 처리가 필요하면 wsgi 미들웨어를 통해 파이썬 어플리케이션으로 리퀘스트 전달
  4. 파이썬 어플리케이션이 리퀘스트를 받아 처리 후 wsgi 미들웨어 - 웹서버를 통해 리스폰스 리턴.

의 구조라고 할 수 있다.

정리하자면, 상식대로 웹 서버 위에 서버 어플리케이션이 올라가는데 이 어플리케이션과 웹 서버간의 커뮤니케이션을 위해 wsgi 미들웨어가 존재하는 것. 이 미들웨어를 어플리케이션을 적재하는 어플리케이션 컨테이너라고도 할 수 있다. 자바는 잘 모르지만, 자바 서블릿 컨테이너도 동일한 개념으로 보인다.