제목 : 웹 서버는 무엇이고, local, production 차이는 무엇일까?
웹 서버에 대한 내용을 다루는 이유
우리는 어플리케이션을 배포 할 때, 항상 Server 를 사용한다.
이는 보통 알려진 프론트엔드, 백엔드, 할 것 없이, 모든 영역에서 사용한다.
개발을 위해 테스팅을 할 때도, 배포를 할 때도, 마이크로서비스 또한 서버를 사용한다.
나의 의문점은 웹 페이지를 서빙 해 주는 웹 서버 자체에 있었다.
개발 도구의 편의성이 너무 높아, 내가 어떤 웹 서버를 사용하느냐는 신경 쓸 틈도 없이,
웹 페이지의 결과를 브라우저에서 너무 잘 보여주고 있었다.
웹 페이지를 load 하기 위해 가장 먼저 제공하는 파일은 보통 index.html
이므로,
그냥 나의 컴퓨터 자체가 index.html
에서 원하는
JavaScript
CSS
html
과 같은 파일들을 알아서 load 한다고 생각했다.
클라이언트는 파일을 요청 (GET or HEAD)할 뿐이지,
상호작용 하는 과정은 없다고 생각했기 때문이다.
그런데, 생각 해 보니까 클라이언트가 요청하는 경로는 웹 서버가 어떻게 해석하며,
웹 서버는 수 많은 클라이언트의 요청에 어떻게 대처하는가? 같은 질문이 떠올랐다.
이미 정적 파일로 제작되었거나, 빌드된 결과에 의해 정적 파일 형태로 생성되었다고 해서,
웹 결과물을 제공 해 주는 특정 프로그램이 없다는 것이 아니며,
요청의 분산과 자료 요청에 효과적으로 대응하는 Web Server 프로그램이 필요하다는 것을 깨닫았다.
WAS (Web Application Server) 를 만드는 데에 치중하다 보니,
프로그램에 사용하던 Nginx 조차 프론트에서 적극 활용되고 있다는 사실을 잊게 된 것이다.
이번에 React 를 제대로 다루기 전에, 배움의 한계점 자체를 높이기 위해 기초를 튼튼히 하기로 결심했다.
그리고, 최근 웹 제작 라이브러리 혹은 프레임워크의 진화가 이루어지며, CSR 뿐만 아니라, SSR 도 중요하다.
(Client Side Rendering -- Server Side Rendering)
빌드된 파일을 정적으로 운용하고, 이를 사용자가 자체 브라우저에서 렌더링한다면 CSR 이며,
사용자의 렌더링 계산을 줄이고, 쾌활한 사이트를 제공하기 위해 서버에서 계산을 분담한다면 SSR 이다.
위에서 말한 CSR, SSR 에 대한 나의 의견은 완벽히 정확하지 않으며, 다양한 의미를 담고 있다.
사용자에게 요청받는 사이트를 제공하며,
혹은 자주 요청받는 사이트를 캐싱하기도 하며, (서버 내부 계산 효율화)
사용자의 트래픽을 여러 서버로 분산시키기도 하는 웹 서버를 지금부터 제대로 배우고자 한다.
Web Server 란 무엇인가?
먼저, 위키백과에서 정의한 "웹 서버" 에 대한 정의를 말하자면,
웹 브라우저와 같은 클라이언트로부터 HTTP 요청을 받아들이고,
HTML 문서와 같은 웹 페이지를 반환하는 "컴퓨터 프로그램" 을 의미한다.
대다수의 웹 서버는 Server-side scripting 를 지원한다.
이는 서버 소프트웨어의 변경 없이도, 웹 서버가 수행 할 동작을
분리된 Server-side script 언어에 기술 할 수 있다는 의미이다.
이를 통해, HTML 문서를 동적으로 생성하는 것을 말한다.
flowchart LR
subgraph WebServer ["Web Server"]
Process("HTTP Server Process")
File("File System")
File --> Process
end
Network("Network...")
Process <--> Network
subgraph Clients ["클라이언트"]
Client1("클라이언트 1")
Client2("클라이언트 2")
Client3("클라이언트 3")
Client1 ~~~ Client2 ~~~ Client3
end
Network <--> Clients
웹 서버는 웹 뿐만 아니라, 프린터, 라우터, 웹 캠과 같은 임베딩 장치에서도 사용된다.
Web Server 들의 공통 기능
- HTTP
- 통신 기록
- 정적 콘텐츠 관리
- HTTPS 지원
- 콘텐츠 압축
- 등등...
웹 서버, 웹 어플리케이션 서버는 모두 https 를 사용한다 (production 에서)
단순히 웹 서버는 HTML 파일과 정적 파일을 serving 한다는 나의 안일한 생각이 부끄러워지는데,
생각 해 보면 https 사용을 위한 SSL과, 도메인 인증, 리버스 프록시 지원을 해 준다.
Web Server 와 CGI
CGI 는 Common Gateway Interface 의 약자이다.
CGI 는 정적인 리소스를 전달하는 "웹 서버" 상에서, 사용자의 프로그램을 동작시키기 위한 조합이다.
수많은 웹 서버 프로그램은 CGI 기능을 이용 할 수 있다.
서버 프로그램에서는 정보를 동적으로 생성하고, 클라이언트에 송신하려는 것이 불가능했다.
이로 인해, 서버 프로그램에서 다른프로그램을 불러내고, 그 처리 결과를 클라이언트에 송신하는 방법이 고안되었다.
이를 위해 서버 프로그램과 외부 프로그램과의 연계법을 정한 것이 CGI 라고 한다.
CGI 는 환경 변수나 표준 입출력을 다룰 수 있는 프로그래밍 언어라면 구별하지 않고 확장하여 이용하는 것이 가능하다.
실제로, Node.js 환경으로 웹 서버를 만들 수도 있다. (기본 라이브러리, 혹은 Express 로 구현 가능)
CGI 는 아래와 같은 동작을 수행한다. - CGI를 경유하여 실행되는 프로그램을 CGI 프로그램 이라 부른다.
- CGI 프로그램은 웹 서버가 클라이언트로부터 요청에 응답하여 동작한다. (동적 컨텐츠 말하는듯)
- 만약에 프로그램에 대응하는 URI 로의 요청이 있다면, 서버는 프로그램을 CGI 의 결정에 따라 호출한다.
- CGI 프로그램의 정보 입력은 명령중 인수, 환경변수, 표준 입력 에 의해 이루어진다.
- 프로그램의 표준 입력에 출력된 데이터는 웹 서버를 경유한 클라이언트에게 보내진다.
- 이 데이터는 정당한 HTTP 헤더로 시작해야 한다.
개인적으로 생각했을 때, 환경 변수나 표준 입출력을 다룰 수 있는 프로그래밍 언어가 CGI 프로그램이 될 수 있다면,
우리가 들어봤을 법한 언어들은 거의 전부 CGI 프로그램으로서 만들어 질 수 있다는 이야기이기도 하다.
저 레벨 언어인 C, C++ 와 같은 언어로 CGI 프로그램을 이루고 웹 서버가 되기도 하지만,
최상위 레벨 언어인 JavaScript, Python 으로도 웹 서버가 만들어 지는 것을 보니,
경량화와 속도를 위해서 httpd, nginx 가 사용되고,
접근성과 편의성을 위해 python 이 사용되는 이유를 알 수 있었다.
위키백과의 설명 이미지를 mermaid 로 표현하자면,
flowchart LR
Web-Users
HTTP
subgraph Server-Program-Group ["서버 프로그램 그룹"]
direction TB
Web-Server("웹 서버")
CGI("CGI")
Gateway-Program("게이트웨이 프로그램")
Web-Server <--> CGI
CGI <--> Gateway-Program
end
Web-Users <--> HTTP
HTTP <--> Server-Program-Group
Web Server 는 무엇이 유명할까?
알 만한 프로그램도 있고, 최근에 갑작스럽게 떠오르는 Web Server 들도 있다.
- Apache httpd - https://httpd.apache.org/
- Nginx - https://nginx.org/
- Cloudflare - https://www.cloudflare.com/ko-kr/
- OpenResty - https://openresty.org/en/
위의 프로그램들은 상용 제품인 것도 있으며, 오픈소스 인 것도 존재한다.
Apache httpd 웹 서버
httpd 이름의 유래는, HTTP Daemon 으로부터 왔다고 한다.
나는 httpd 를 처음 접한 프로그램이 Docker 였다.
Docker 이미지 중, httpd 를 사용하는 예제를 따라 해 본적이 있었다.
그 때는 왜 httpd 라는 프로그램을 사용하는지도 모르고 이미지 컨테이너 실행을 한 뒤,
80 번 포트에서 웹 페이지를 본 경험이 있다.
지금에서야 httpd 가 대표적인 웹 서버라는 것을 깨닫게 되었다.
Apache 재단에서 만들었으니, Java 가 사용되었나? 싶었는데, 프로그램의 대부분은 C 로 이루어져 있다.
(Apache Topcat 이랑 헷갈린 듯 - 내가)
httpd - Github
https://github.com/apache/httpd?tab=readme-ov-file
httpd 는 들어오는 요청을 다루기 위해 다중 프로세스를 사용하는 웹 서버이다.
정확히는, 서버 상황에 맞게 동일한 웹 서버를 생성하고,
각각의 웹 서버는 트래픽에 따라 최소 ~ 최대 로 설정된 쓰레드 풀을 생성하고 유지한다.
생성된 최소 ~ 최대 쓰레드 풀은 클라이언트로부터 요청을 처리하는 역할을 맡는다.
요약하자면,
- 부모 프로세스 == 싱글 스레드
- 자식 프로세스들 ==
conf
에 설정된ThreadsPerChild + 1
만큼의 스레드를 생성 - 자식 프로세스들은 지정된 서버의 구성을 지시받음.
만약 시작 서버가 2개이고, ThreadsPerChild 가 20 이라면
---
title : httpd 프로그램의 초기 프로세스 현황 (예시)
---
flowchart LR
Parent1{{"Parent"}}
Parent1 --> Child1("Child1")
Parent1 --> Child2("Child2")
Parent1 --> Child3("....")
Parent1 --> Child4("Child21")
Parent2{{"Parent"}}
Parent2 --> Child5("Child1")
Parent2 --> Child6("Child2")
Parent2 --> Child7("....")
Parent2 --> Child8("Child21")
이러한 초기 pstree 형태를 가지게 된다.
그렇다면, 이 2 개의 서버는 초기에 40개의 동시성 커넥션을 다룰 수 있다.
나중에 httpd
프로그램의 설정 파일(xxxx.conf
) 에서 최소, 최대 자식 쓰레드를 기입함으로서,
리소스 할당을 조절 할 수 있다.
Nginx 웹 서버
httpd 의 스레드 하나가 유저의 커넥션 연결을 다루었다면,
nginx 의 요청 응답 (커넥션) 방식은, "비동기 이벤트 기반 구조" 를 가진다.
예전에 Docker 와 k8s 를 다룰 때 Nginx 를 접했는데,
k8s (kubernetes) 에서는 ingress 로 사용하여
Reverse Proxy 및 Load Balancer 로 사용했었다.
하지만, httpd 와 마찬가지로 Nginx 도 정적 파일 serving 기능이 존재한다.
Nginx 에서 각각의 웹 서버에 트래픽을 분산하는 것에 집중하기 위해,
Nginx 내부 설정 파일에 HTTPS 인증을 위한 SSL 인증서를 저장하여 사용한다. (httpd) 도 가능.
Nginx 는 가벼우며, 리버스 프록시와 로드 밸런싱에 대한 지원이 풍부하여
각각의 웹 서버에 트래픽을 분산하는 데 자주 사용된다.
Github 코드베이스 (Nginx)
https://github.com/nginx/nginx
Cloudflare 웹 서버?
요즘 웹 서버 서비스를 담당하는 순위표에서,
- Apache httpd
- Nginx
- IIS - 마이크로소프트
- GWS - 구글 웹 서버
- Cloudflare - 클라우드플레어
클라우드플레어의 순위표가 굉장히 높아졌다.
Cloudflare 의 서비스를 읽어보며 느낀 것은, 위에서 다룬 "웹 서버" 의 기능과 동일하지 않다는 것이다.
Cloudflare 는 httpd 와 nginx 와 동일한 역할로, 웹 사이트를 제공한다.
그런데, 그 방식은 가까이서 보았을 때 다르다.
"일반적인 웹 서버와 무엇이 다른가?"
Cloudflare 에서 웹 사이트를 제공하는 방식이 2 개가 존재한다.
정확히는, "원본 웹 서버" 는 nginx 와 같은 웹 서버로 작성하고, CDN + Reverse-Proxy 로 사용하거나,
아예 CDN 워커를 만들어서 웹 사이트 정적 자산 (html, css, js, img, 등등..) 을 전달하여,
원본 서버가 없어도 되게 만든다.
CDN
: Content Delivery Network 의 약자. 자주 사용되는 정적 파일을 "캐싱" 하여 제공한다.Reverse-Proxy
: 우리가 웹 사이트를 직접 찾아가기 위해 "정확한 주소" 를 알고 가는 것이 아니라,
리버스 프록시 역할을 하는 서버의 주소에 입력된 URI 에 따라, 해당 주소에 알맞는 웹 서버에 요청을 넣는다.
그렇다면, Cloudflare 가 어떻게 웹 서버의 역할을 해 주는고... 하니,
Cloudflare 는 웹 호스팅의 역할을 해준다.
원본 웹 서버가 존재한다면, Cloudflare CDN 이 먼저 클라이언트가 요청한 정적 자산이 존재하는지 검색하고,
존재하지 않는다면, 웹 서버에게 요청을 넣는다. (캐싱)
그러나, 클라이언트가 요청한 정적 자산이 캐싱된 상태라면, 원본 웹 서버에게 요청을 넣지 않고, 스스로 응답한다.
만약에 원본 웹 서버가 없다면, Cloudflare CDN 은 등록된 정적 자산을 기준으로 웹 사이트 호스팅을 한다.
이러한 방식을 "서버 리스" (Serverless) 라고 한다.
보안이 중요해진 시대에서, 최근에 디도스 공격을 방어 한 사례로 유명해져
상용 사이트임에도 불구하고 사용자가 굉장히 많다고 한다.
지금까지의 내용을 요약하자면,
전통적으로 고객과의 커넥션을 직접 관리하여 스레드로 연결하는 웹 서버는 Apache httpd 이며,
리소스를 아끼고, 중간 서버로서의 기능을 갖춰 모듈처럼 사용할 수 있는 경량화 웹 서버는 Nginx 이다.
그리고, 상용으로 사용되지만, 대표적으로 서버리스로 웹을 호스팅 할 수 있게 도와주며,
웹 서버의 자산을 스스로 캐싱하여 전달하고 원본 서버의 계산을 줄일 수 있게 해 주는 것이 Cloudflare 이다.
로컬 테스팅 과정에서는 어떤 웹 서버가 사용될까?
우선, 우리는 위에서 다양한 웹 서버에 대해서 다루어 보았다.
"어떤" 환경에서 웹을 개발하냐에 따라서 웹 서버는 달라진다.
나는 먼저 React 를 개발하기 전에, 웹 서버를 공부하겠다고 말했다.
React 를 개발 할 때, 대부분의 사람들은 NPM 모듈과 명령어를 통해 React 웹사이트를 볼 것이다.
(대부분이라고 말한 이유는, React CDN 을 통해서 JS 를 작성하는 사람이 있을 수도 있다.)
React 는 NPM 에서, create-react-app
명령어를 통해서 템플릿을 생성한다.
이 때, React 는 JSX 혹은 TSX 를 사용하며, 스타일링을 위해 다양한 css 확장자를 사용할 수 있다.
예시로, .scss
혹은 .sass
등등이 있다.
이러한 파일들을 최종 파일인 js
, html
, css
로 컴파일하기 위해, WebPack 이 사용된다.
개발 과정에서 발생하는 변경 사항을 항상 빌드하고 빌드 파일을 통해 확인하는 것이 아니라,
Webpack 의 DevServer 를 통해 확인한다.
이 때, Webpack 에서 사용되는 기본 개발 서버는 Express 이며,
선택에 따라 Fasify 로 선택 할 수도 있다.
Webpack 이 뭘까?
위에서 간단히 Webpack 이 React 라이브러리를 컴파일 할 때 어떤 행동을 하는지 작성했지만,
Webpack 은 정확히 번들링 도구이다. (Bundler)
우리가 작성한 JSX 혹은 TSX, 혹은 SCSS, SASS 파일, 그리고 JS or TS 파일들은
빌드 시 정적 파일로 컴파일된다.
React 라는 라이브러리는 코드를 통해 컴포넌트를 계층화 시켰지만,
빌드 후에는 하나의 파일로 합쳐진다는 의미이다.
그렇다면, 개발 폴더에서 작성된 수많은 파일과, 나눠진 컴포넌트들은 어떻게 파트별로
하나의 파일로 합쳐질까?
위의 역할을 수행 해 주는 프로그램이 바로 Webpack 이다.
프로덕션에 올라갈 정적 코드, 그리고 html, css 파일이 어떻게 구성될 지를 결정 해 주는 것이 Webpack 이다.
혹은, 개발 시 코드 파일의 변화를 감지하고 실시간으로 반영 해 주는 것도, Webpack 이다.
사실, Webpack 자체도 중~상급 포스팅 주제이기 때문에, 설명하기엔 너무 긴 감이 있다.
요약하자면
- 로컬에서 웹 서버 개발 시, 어떤 웹을 개발하냐에 따라 웹 서버는 달라질 수도 있다.
- 하지만, NPM 과 함께 웹 개발 시, Webpack 을 사용 할 것이다. (EX - React)
- Webpack 의 기본 웹 서버는 Express 이며, Fastify 를 선택 할 수도 있다.
- 그러나, 대부분의 경우 Webpack 을 추출하여 사용하는 경우는 없다.
- 따라서, 대부분의 경우 Express 를 사용한다고 말할 수 있다.
- (Next.js) 는 잘 모르것다.
프로덕션 과정에서는 어떤 웹 서버가 사용될까?
위에서 언급했던 Cloudflare 과 같이, 정적 자산으로 호스팅하는 경우가 굉장히 많아졌다.
당연히 웹 사이트를 게시하기 위해 서버를 따로 장만하여 운용하는 경우는 거의 없을 것이다.
옛날에는 WAS(백엔드 or 마이크로서비스) 와 비슷하게, VM 에 서버를 직접 장만하여 연결했다고 하는데,
요즘은 Vercel 이나, Netlify, Github Pages 와 같이, 정적 리소스를 통해 웹 사이트를 제공한다.
CDN 호스팅이 아닌, 이전 방식의 웹 사이트 배포는 어떻게 수행되었을까?
웹 사이트 호스팅은 현재 시대에는 정말 쉽다. (25-05-13 기준)
Vercel, Nelify 와 같은 대표적인 사이트들은 그냥 Github Repo 와 연결해 주기만 해도 끝이기도 하다.
물론, 도메인 변경과, SSL 새로 지정과 같은 행위들은 해당 프로그램 사이트에서 지정 해 주어야 할 것이다.
쉽게 쉽게 사이트를 배포하는 법도 알면 정말 좋겠지만, 나는 웹 서버의 동작을 알고자 한다.
이전 방식의 웹 사이트 배포는, 위에서 다뤘던 Nginx, Apache httpd 를 활용하면 된다.
Nginx, Apache httpd 는 오픈 소스이다.
cdn 을 통해 빠르게 정적 자산을 배포해 주는 Cloudflare 조차도, 스스로 Nginx 를 개조하여 사용한다고 한다.
다시 돌아와서, Nginx 와 Apache httpd 는 웹 사이트를 배포하는 과정이 비슷하다.
CGI 를 만족하는 이러한 웹 서버 오픈소스는, 웹 사이트에 해당하는 자산들을 지정된 위치에 배포 해 주어야 한다.
이 때, https 지원을 위해 SSL 인증서를 등록하거나, HTTP/2 버전을 지원한다.
각자의 오픈소스는 리소스를 어떻게 할당 할 것인지, 경로는 어떻게 지정 할 것인지 선언하는 파일이 존재한다.
Apache httpd, nginx 둘 다 .conf
를 사용한다. 물론, 서로 디렉토리는 당연히 다르다.
하지만, httpd 의 경우, 설정 파일 확장자가 더 존재한다.
두 프로그램 모두, 지정된 디렉토리에 존재하는 홈페이지 정적 리소스를 보관하고,
클라이언트에게 원활히 제공하기 위해 부모 스레드, 자식 스레드를 사용하여 제공한다.
Nginx 는 C 기반이지만, 마치 Node.js 엔진처럼 비동기로 작동하여, 리소스를 예측하기 쉽다고 한다.
httpd 와 Nginx 는 서로 다른 동작 방식을 가지기 때문에, 함부로 언급하지는 않겠다.
이 글을 작성하며 배운 것
React 를 공부하기 전, 문득 내부의 어려운 요소를 공부하는 과정에서 이어지지 않는 지식을 갖추고자
연관된 CS 지식을 공부하고 있다. 의문이 드는 요소는 조사하고, 이를 직접 습득하고 있다.
웹 사이트 배포 및 호스팅이 너무나 쉬워진 세상에서 웹 서버를 공부한다는 것은 다시 돌아가는 행위 일 수도 있다.
신기술을 습득하기도 어려운 세상에서, 이전 기술을 배우는 것은 사실 취업과 거리가 멀 수도 있다.
그러나, 나는 새로운 신기술은 항상 튼튼한 기초를 베이스로 생겨난다고 생각한다.
새로운 기술과 새로운 기술이 합쳐지면 세상 편하게 개발을 할 수는 있겠으나,
누군가는 기초 지식을 통해 해당 기술을 최적화하여 대체하기 매우 쉽다고 생각한다.
이 글을 작성하며 "웹 서버" 에 대해서 배웠는데,
내가 WAS (NestJS) 를 프로덕션에 배포 할 때 사용했던 Nginx 의 역할에 대해서 다시 재고 해 보았다.
Nginx 를 SSL 터미네이션 프록시 + 리버스 프록시로 사용했는데,
공식 사이트를 보니, 정말 다양한 기능을 지원하고 있었다.
개인적인 생각으로, CGI (Common Gateway Interface) 기능을 가진 웹 서버는,
정적 자산만을 전송하는 것에 집중하지 않고, CGI 프로그램에 훨씬 비중을 둔 서버는 WAS 라고 생각한다.
웹 서버 --> 웹 어플리케이션 서버(WAS) 인 이유를 알게 된 것 같다.
특히, React 를 공부하면 항상 Webpack 의 도움을 받게 될 텐데,
이에 대해 깊이 알지는 못해도, 어떤 역할을 하는지 정확하게 알게 되어서,
나중에 서버 사이드 라이브러리를 사용 할 때 도움이 될 것이라고 생각한다.
아직 작성해야 할 글이 너무나 많은데, 나의 학습 속도가 조금 느린 것 같아서 집중해야 할 것 같다.
참고 사이트
위키백과 (웹 서버)
https://ko.wikipedia.org/wiki/%EC%9B%B9_%EC%84%9C%EB%B2%84
위키백과 (아파치 HTTP 서버)
https://ko.wikipedia.org/wiki/%EC%95%84%ED%8C%8C%EC%B9%98_HTTP_%EC%84%9C%EB%B2%84
위키백과 (CGI - Common Gateway Interface)
위키백과 (Nginx)
https://ko.wikipedia.org/wiki/Nginx
netcraft (HTTP 서버 랭킹)
https://www.netcraft.com/blog/january-2024-web-server-survey/
Web Server 제공 업체, 오픈소스 공식 사이트
- Apache httpd - https://httpd.apache.org/
- Nginx - https://nginx.org/
- Cloudflare - https://www.cloudflare.com/ko-kr/
- OpenResty - https://openresty.org/en/
httpd 깃허브
https://github.com/apache/httpd?tab=readme-ov-file
Medium 글 (서버와 인터페이스 - Web Server, CGI, WAS, WSGI 에 대한 이해)
Medium 글 (Apache HTTP Server -- Multi-process architecture)
https://medium.com/brundas-tech-notes/apache-http-server-multi-process-architecture-8fb14438a2ce
'Web-Server > 웹 지식' 카테고리의 다른 글
HTML 문서 정식 태그 "전부" 공부하기 - 4편 (코드 작성 및 구현까지) (0) | 2025.05.30 |
---|---|
HTML 문서 정식 태그 "전부" 공부하기 - 3편 (코드 작성 및 구현까지) (1) | 2025.05.28 |
HTML 문서 정식 태그 "전부" 공부하기 - 2편 (코드 작성 및 구현까지) (0) | 2025.05.26 |
HTML 문서 정식 태그 "전부" 공부하기 - 1편 (코드 작성 및 구현까지) (0) | 2025.05.24 |
React 를 다시 공부하기 전 스스로에 대한 고찰 및 비판 (2) | 2025.05.10 |