파이썬 웹 서비스 개발 101 (was, Cgi, 웹서버 ~ Wsgi 찍먹)

웹 서비스를 만드는 백엔드 개발자로써 웹서비스에 대해 한 번 짚고 넘어가봅시다.

그리고 한 발자국 더 나아가 웹 서버의 종류와 역사에 대해서 훑어봅니다.

웹 서비스가 뭘까?

먼저 서비스가 뭔지에 대해 고민해봅시다.

서비스란 다른 사람 또는 어떤 단체나 조직을 위해 수행되는 활동이나 혜택을 의미합니다.

갈비집에서 무료로 손님들에게 제공해주는 후식 요구르트나 냉면같은걸 주는 행위를 고객 서비스가 되겠습니다. (후식 요구르트나 냉면은 덤이구요)

웹 서비스도 비슷합니다. 갈비집에서 장소만 바뀌었죠. 웹 상에서 사용자가 요청한 정보를 사용자에게 주는것을 웹 서비스라고합니다.

웹 서비스란 인터넷 위에서 서로 다른 시스템(사람들, 조직)끼리 데이터를 주고 받을 수 있도록 도와주는 소프트웨어입니다.

웹 서비스의 대표적인 예로 날씨정보 제공해주는 웹 서비스, 카카오톡으로 유효한 사용자인지 확인할 수 있게 해주는 게 있겠습니다.

웹 서비스는 뭘로 이루어져있을까? 서버-클라이언트

이야기를 들어보니 서비스라는건 결국 혜택을 주는 사람과 혜택을 받는 사람이 있네요.

웹 서비스도 마찬가지입니다. 웹 서비스는 서버와 클라이언트로 이루어져있습니다.

  • 서비스를 제공하는 서버

  • 서비스를 제공받는 클라이언트

그리고 이러한 웹 서비스는 인터넷 위에서 동작하기 때문에 데이터를 주고 받을 때는 HTTP 라는 규칙을 지켜야합니다.

예를 들자면 서버는 영어로 hi를 클라이언트에게 보내지만 클라이언트가 영어를 알아 듣지 못한다면 말짱 도루묵이죠. 이러첨 통신을 할 때 어떤 형식의 데이터를 보낼지, 한 번에 얼마나 보낼지등을 미리 정해놓은게 HTTP라고 간단히 말할 수 있습니다.

다시 한 번 정리하자면

  • 웹 서버 : 클라이언트의 요청을 받아 요청을 처리하고(예를 들자면 어느 데이터를 수정/삭제/추가 또는 전달달라는) 그 결과에 맞는 응답을 클라이언트에게 보내줍니다

  • 웹 클라이언트: HTTP 규칙에 맞춰 서버에게 요청을 보내는 쪽입니다. 이때 요청은 데이터를 요구하는 걸수도 있고 데이터 수정/삭제/추가 등이 될 수도 있습니다.

그래서 웹 프로그래밍이란

결국엔 웹 서비스를 만드는게 웹 프로그래밍입니다. HTTP로 통신하는 서버와 클라이언트를 만드는거죠.

  • 대표적인 웹 클라이언트로는 브라우저가 있습니다. 서버에게 요청을 하고 서버에게 받은 응답 결과(html, css, 자바스크립트등)를 우리들(사용자)이 보기 편하게 볼 수 있게 해주고 인터넷에 접속에 웹페이지 탐색을 쉽게 도와줍니다.

  • 브라우저 말고도 웹 클라이언트가 될 수 있는 것은 많습니다. linux 명령어 curl로 보내는 요청이라든가요.

그렇다면 웹 서버는?

인터넷 위에서 클라이언트의 요청을 받아 처리하는 쪽을 통칭해서 웹 서버라고 했는데요. 조금 우리는 서버 개발자니까 조금 더 깊이 알아봅시다.

조금 더 자세히 말하자면 웹 서버와 WAS로 나눌 수 있거든요.

웹서버, 동적페이지, 정적 페이지

웹 서버와 WAS에 대해 이야기 하려면 먼저 동적페이지와 정적 페이지에 대해 알아야합니다.

정적페이지

  • 정적페이지 static page, 문자 그대로 멈춰있는 페이지를 의미합니다.

  • 회사 소개 사이트, 프로덕트 랜딩 페이지 그리고 인터넷이 만들어진지 얼마 안됐을 때 논문만 게시되어있던 사이트들 또한 정적페이지들로 만들어졌습니다.

  • 누가 언제 요구하더라도 항상 같은 내용을 표시하기때문에 모든 사용자가 같은 결과를 볼 수 있습니다.

동적페이지

  • 동적페이지 dynamic page 움직이는 페이지입니다. 같은 요청을 클라이언트가 하더라도 어떤 클라이언트, 언제 요청을 보냈는지등에 따라 그 결과가 달라지는 페이지를 의미합니다.

  • 시시각각 바뀌는 시간을 표시해주는 페이지, 인터넷 쇼핑몰 장바구니페이지(사용자마자 다른 물건들을 표시해줘야하죠)

정리하자면
- 사용자가 요청 받기 전에 이미 정적인 페이지들이 만들어져있는 상태
- 사용자 요청 받고 나서 이를 처리(데이터를 가공한다든가)한 뒤에 그 처리 결과를 HTML에 담으면 동적페이지 (사용자가 요청한 시점에 반환 데이터를 만들죠)

웹 서버와 WAS

인터넷이 만들어진지 얼마 안되었을 때는 정적인 페이지만 웹 서버에서 제공했습니다. 하지만 인터넷이 발달하면서 동적인 페이지에 대한 요구사항이 늘어 웹 서버와 다른 별도의 프로그램을 필요로 하게 됩니다.

예를 들자면 쿠팡, 11번가등 인터넷 쇼핑몰이 발전하면서 각 사용자들에게 마이페이지, 장바구니같은 페이지 구현해 줘야 할 필요가 커졌어요.

각 사용자들에 대한 데이터를 데이터베이스에서 뒤지고 이에 맞는 정적페이지를 만들어줘야 하는 상황입니다. (어느 사용자가 어느 상품을 장바구니 담았는지는 데이터베이스에 저장되어있을테니깐요)

따라서 동적인 페이지를 요청 받았을 때 이를 처리하는 서버를 WAS, Web Server Application이라고 부르게 됩니다.

이 WAS는 웹서버로부터 동적인 요청을 받아 처리합니다.

이름역할
웹서버
- 클라이언트로 HTTP 요청을 받고 이 요청을 분석하고 정적페이지인 HTML, CSS, 이미지, CSS, JS등을 반환- 클라이언트로부터 정적인 요청을 받아 처리 후 정적 페이지를 반환한다.
- 만약에 동적페이지 처리가 필요하다면 WAS에 처리를 넘긴다아파치 httd, 엔진엑스,
WAS- 웹 서버로부터 동적 페이지 요청을 받으면 이를 처리하고 그 결과를 웹 서버로 반환
- 프로그램 실행, 데이터베이스 연동기능아파치 톰캣, uWSGI

WAS (Web appplication Server)방식에서는 웹 서버가 정적처리를 그리고 필요시에 동적처리를 WAS에게 넘깁니다.

동적 페이지 처리는 데이터베이스와 연결되는 작업이고 이 작업은 정적 페이지보다 수십배므이 메로리를 소비하기 때문입니다. 따라서 모든 요청을 웹서버나 WAS에서 처리하기보다 역할을 구분짓는게 서버에 무리가 덜 가겠죠.

현대에서는 두 서버의 역할이 더 전문적 🙇‍♀️으로 변했습니다

  • 웹 서버 = 정적요청처리가 주역할이지만 캐시, 프록시, 로그, 클라이언트 연결수 제한등의 역할

  • WAS = WAS 는 더 다양해지는중! 대부분의 WAS는 클라이언트 요청 직접 처리하는 기능 제공하지만 WAS 와 웹 서버 기능상 적합하지 않기에 대규모 사이트나 운용환경에서는 비추 합니다.

그래서 장고로 만든 파이썬 앱도 웹서버? WAS?

근데 이 웹서버 가 flask, Django, FastAPI로 만든 어플 만든 웹 어플리케이션과 뭔상관일까요?

장고나 플라스크같이 파이썬 웹프레임워크로 만든 앱도 웹 서버나 WAS인가요?

아니요! 다른 서버로부터 요청을 받아 이에 맞게 데이터베이스에서 데이터를 가공해 반환한다는 한다는 점에서 서버라고 할 수 는 있지만 웹서버와 WAS 둘 다 아니랍니다.

  • 웹서버는 HTTP 요청 처리, 주로 정적 콘텐츠를 제공하는데 초점이 맞춰져있고 파이썬 웹 프레임워크로 만든 어플리케이션은 DB 연동, 비즈니스 로직처리, 동적컨텐츠 생성에 초점이 맞춰져있습니다. 그러니 웹 서버는 아닙니다!(장고 공식문서에도 확실히 나와있어요)

  • 우리가 만든 파이썬 웹 어플리케이션도 동적요청을 처리하니까 (요청받아서 DB에서 작업을 하고 결과를 반환하니!?) WAS일까요? 아니요.
    파이썬 어플리케이션은 범용 웹서버인 Apache, Nginx는 직접 통신 할 수 없기 때문에 WAS라고 부를 수는 없습니다.(기본적으로 웹서버에서 받은 동적요청을 WAS로 넘겨야하기때문에 통신은 필수..) 따라서 웹서버와 파이썬 어플리케이션 사이 통신 규격인 WSGI 를 구현한 WSGI 서버를 필요로 하게 되는데 이게 WAS 의 한 종류랍니다...

그래서 파이썬 어플리케이션은 어떻게 요청을 처리하나? 그래서 이런 그림이 완성됩니다.

그러니까 파이썬 웹 앱에서는 이 WSGI 규격만 맞추면 사실 어느 웹 서버에든 실행가능합니다. 그런데 아파치나 nginx같이 범용적인 웹서버에서는 이 WSGI 처리 기능이 없어서 웹 서버와 파이썬 웹앱 사이에 WSGI 서버가 생기게 됩니다.

이 wsgi서버가 중간에서 통신 규격을 처리해주거든요!

그리고 파이썬 진영에서 이 WSGI 규격을 준수하고 있습니다. 그래야 웹 서버와 연동을 할 수 있는 최소 기준이 맞춰지니깐요. (WSGI 스펙은 PEP333에도 명시되어있습니다)

WAS의 과거; 그런데 WSGI 전에 CGI라는게 있었는데요

우리는 백엔드 개발자니까 WAS와 WSGI가 어떻게 나오게 되었는지 태초 마을부터 알아봅시다.

먼저 CGI에 대해 살펴봐요.

초기에는 원래 1번만(웹서버) 필요했었는데 동적인 요청 처리를 위해 원래 WAS보다 CGI라는것이 먼저 있었습니다. 그러나 기술적인 문제가 있어 그 대안으로 3번과 4(WAS)번이 나오게 되었습니다. 먼저 CGI 프로그램에 대해 알아보세.

웹 서버와 WAS는 어떻게 요청 정보를 주고 받나? CGI

정적인 요청을 처리하는 웹서버와 동적인 요청을 처리하는 별도의 프로그램사이에서(여기에선 WAS아님!) 정보를 주고 받는 일종의 규칙을 정의한게 바로 CGI 입니다.

CGI, 웹 서버와 동적 요청을 처리하기 위한 프로그램간의 규약
Common GateWay Interface. 다음과 같은 사항을 규정하고 있다
- 환경변수
- 표준 입출력
- 커맨드라인 인자

이름에서도 알 수 있듯이 인터페이스입니다. 프로그래밍 언어나 스크립트가 아니라 규격 을 의미하죠. 위에 나와있는 규정 사항을 지켜서 구현한게 CGI 프로그램이 됩니다. 따라서 특정 언어에 종속받지 않고 CGI 프로그램을 만들 수 있습니다.

  • 다시 정리하자면 CGI는 웹 서버와 독립 적인 프로그램(프로세스) 사이에 정보를 주고 받는 규격 .

  • 동적인 요청을 처리하는 방법으로는, 웹 서버에서 우리가 작성한 프로그램(동적인 요청을 처리하는 별도의 프로그램= CGI 프로그램을 의미)을 직접 호출해 개별 프로세스를 생성합니다.

  • 위 그림처럼 웹 클라이언트 -> 요청 -> 웹서버 -> CGI 프로그램 실행(=프로세스 실행)

보시면 아시겠지만 웹서버에서 CGI 프로그램을 호출하면 별도의 프로세스가 생깁니다. 요청에 따라 프로세스를 생성하기에 점유 메모리 요구량이 커져 시스템 부하가 올 수 있죠.

따라서 현재는 이러한 CGI 방식을 거의 사용하지 않고 있습니다. 😅

CGI 대안(스크립트엔진 OR 데몬가동)

  1. 스트립트 엔진

CGI 프로그램과 같은 역할(동적 요청 처리하는)을 하는 어플리케이션을 스크립트 언어(perl, php등) 으로 작성하고 이러한 스크립트를 처리하는 스크립트 엔진(인터프리터) 를 웹 서버에 내장 🎶 기존 CGI 프로그램에서는 요청마다 프로세스를 생성하는 오버헤드를 줄일 수 있다!

아파치 웹서버 에서 사용하는 mode_perl, mode_php는 스크립트 엔진을 웹 서버에 내장 시켜 어플리케이션 처리 고속화하기 위해 개발 되었습니다. 파이썬에서는 mod_wsgi 모듈을 사용하고 있습니다.

  1. 데몬방식 ✅

요청을 처리하는 프로세스를 미리 데몬으로 기동시켜 놓은 후 웹서버 요청을 데몬으로 처리합니다.

  1. 사전 프로세스 생성: 서버 시작 시 미리 프로세스를 생성하여 대기 상태로 유지합니다.

  2. 요청 처리: 클라이언트의 요청이 들어오면, 이미 생성된 프로세스가 요청을 처리합니다.

  3. 프로세스 재사용: 요청 처리 후 프로세스를 종료하지 않고 다음 요청을 위해 대기합니다.

  4. 리소스 효율성: 매 요청마다 새로운 프로세스를 생성하지 않아 시스템 리소스를 절약합니다.

파이썬같은 경우에는 데몬 방식도 mod_wsgi모듈을 사용합니다. 이 모듈을 웹 서버 내장 방식으로도 실행가능하고 별도 데몬 방식으로 실행이 가능하네요.

🔥🔥🔥🔥 파이썬에서 웹 서버 연동용으로 사용하는 mod_wsgi, uwsgi, gunicorn 같은 프로그램들이 웹 서버 nginx, http등과는 별개의 데몬으로 동작한다는 점에서는 WAS라고 할 수 있어요 🔥🔥🔥🔥🔥🔥🔥