HTTP 프로토콜을 기반으로 클라이언트가 웹 브라우저에서 어떠한 요청을 하면 그 요청을 받아 정적 컨텐츠를 제공하는 서버
웹서버는 정적인 컨텐츠를 제공하는 것 외에도 WAS구조에서 동적인 처리를 하는 컨테이너에게 요청을 넘겨주게 되며 처리가 끝나면 응답을 받아 다시 클라이언트로 전송하는 역할을 한다.
e.g. Apache (Apache HTTP Server), NginX
Apache는 하나의 스레드가 하나의 요청을 처리하는 구조이다. 이는 매 요청마다 스레드를 생성 및 할당해야 하기 때문에 많은 리소스가 소요된다.
Apache에는 클라이언트로부터 받은 요청을 어떻게 처리할 것인지에 대해 결정하는 모듈인 MPM(Multi Processing Module)이 있다. 가장 대중적으로 사용하는 MPM에는 Prefork, Worker, Event 방식이 존재한다.
Prefork MPM
하나의 요청에 대해서 하나의 자식 프로세스가 하나의 스레드를 사용해서 처리하는 방식이다. 동시에 여러개의 요청이 들어온다면 생성되어있는 자식 프로세스에서 각 요청을 처리하게 된다. 각 프로세스들의 자원은 독립적이므로 다른 요청이 들어오거나 프로세스 하나에 장애가 발생하더라도 다른 요청에 영향이 가지 않는다는 이점이 있다.
하지만 프로세스가 많아진다면 프로세스가 차지하고 있는 메모리 공간이 크기 때문에 부하가 일어날 수 있다는 단점이 있다.
Worker MPM
Prefork와 달리 하나의 자식 프로세스 안에 여러개의 스레드를 사용하고있고 각 요청은 각 스레드에서 처리하게된다. 프로세스 하나의 제한된 스레드 개수가 있는데 그 스레드 수를 넘어가면 새로운 자식 프로세스를 생성해서 처리하게 된다. Prefork 처럼 요청당 프로세스 하나가 아니라 메모리가 절약된다는 장점이 있다. 때문에 Prefork보다 부하 위험성이 덜하다.
스레드끼리 자원을 공유하기 때문에 이러한 점에서 주의를 요한다. 프로세스가 죽으면 다른 스레드들도 같이 죽을 수가 있다.
Event MPM
기본적으로 Worker와 동일한 방식으로 설정된다. 기존 방식에서 요청에 대한 연결을 스레드 혹은 프로세스가 계속 유지하고 있는 경우가 있는데(KeepAlive 등) 대량의 요청에서는 이는 성능이 떨어지고 부하가 일어날 가능성이 있다. 이런점을 해결하기 위해 나온게 Event이다. Event Driven 방식을 적용한 모듈이다. Worker에서 이벤트를 다루는 스레드를 하나 둔 것이 Event MPM이다. 이것을 사용해서 KeepAlive 문제를 해결할 수 있다. 요청을 완료하고 나면 클라이언트는 연결을 유지하고 동일한 소켓으로 추가 요청을 보낼 수가 있다.
Nginx는 Event-Driven 방식으로 Apache와는 다르게 하나의 스레드 내에서 여러 요청을 처리한다. 한 개 또는 고정된 프로세스만 생성하고, 여러 개의 Connection을 모두 Event-Handler를 통해 비동기 방식으로 처리한다.
CPU와 관계없이 모든 I/O들을 전부 Event Listener로 미루기 때문에 흐름이 끊기지 않고 응답이 빠르게 진행되어 1개의 프로세스로 더 빠른 작업이 가능하다. 이 덕분에 메모리를 적게 사용한다.
또한 적은 양의 스레드만 사용되기 때문에 Context Swiching 비용이 적고, CPU 소모가 적다.
👉 Apache와 달리 동시 접속사 수가 많아져도 추가적인 생성 비용이 들지 않는다.
Apache의 경우 웹서버임에도 동적 컨텐츠를 처리할 수 있다.
Nginx는 단독으로 동적 컨텐츠 처리가 불가능하다. 따라서 외부 프로세서로 전달하고 렌더링 된 컨텐츠를 다시 전송할 때 까지 기다려야 한다 ⇒ 프로세스 속도 저하
❗️ 하지만 정적 컨텐츠의 경우, 설계 아키텍처 구조상 Nginx가 적은 비용으로 효율적인 서비스를 제공한다.
Nginx
Apache
Nginx
Apache
Apache | NginX |
---|---|
요청 당 스레드 또는 프로세스가 처리하는 구조 | 비동기 이벤트 기반으로 요청 |
CPU/메모리 자원 낭비 심함 | CPU/메모리 자원 사용률 낮음 |
NginX보다 모듈이 다양 | Apache에 비해 다양한 모듈이 없음 |
PHP 모듈 등 직접 적재 가능 | 많은 접속자들 대응 가능 |
안정성, 확장성, 호환성 우세 | 성능 우세 |
동적 컨텐츠 단독 처리 가능 | 동적 컨텐츠 단독 처리 불가능 |
💡 결론: Apache, Nginx 어느 것이 더 좋다! 라고 단정 지을 순 없다. 서비스의 특성과 상황 등을 고려하여 선택하자!