Nginx란 무엇이고 왜 사용하는가? (Apache와 차이점)

반응형

Nginx의 등장 이전

최초의 웹 서버는 1995년 UNIX 기반으로 만들어진 NCSA Httpd 였다.

하지만 처음은 다 그렇듯이 NCSA Httpd에는 버그가 상당히 많아서 개발자들이 사용할 때 많은 불편함을 겪었다고 한다.

그래서 이러한 문제를 해결하기 위해 구조도 변경하고 새로운 기능을 추가해 개발된 것이 바로 Apache이다.

 

Apache

Apache는 요청이 들어오면 커넥션을 형성하기 위해 프로세스를 생성하는데

새로운 요청마다 프로세스를 생성하는 것은 시간이 소요되는 작업이다보니 프로세스를 미리 만들어 놓는 Prefork 방식을 사용했다.

새로운 요청이 들어오면 미리 만들어 놓은 프로세스를 가져다 쓰는 방식이다.

만약 만들어 놓은 프로세스가 모두 할당되었다면 추가로 프로세스를 만든다.

 

이러한 구조덕에는  Apache는 다음과 같은 장점들을 가져 나온지 1년도 안된 시점에 세계 1위 웹 서버라는 타이틀을 갖게되었다.

  • 다양한 모듈을 만들어서 서버에 빠르게 기능을 추가
  • 동적 콘텐츠 처리
  • 확장성이 좋아 요청을 받고 응답을 처리하는 과정을 하나의 서버에서 해결

 

하지만 시간이 흘러 컴퓨터 보급이 점점 많아지고 덩달아 사용자의 요청도 많아지면서 "C10K"라는 문제가 발생했다.

C10K는 Connection 10,000개의 문제를 줄인 말이다.

컴퓨터가 많이 보급되면서 덩달아 이용자 수가 많아지면 그만큼 커넥션수도 증가한다.

그렇게 동시 커넥션 수가 10000단위로 넘어가는 순간, 서버는 더 이상 커넥션을 형성하지 못하는 상황이 발생하는 것이다.

이 문제는 Apache의 구조로인한 치명적인 한계 있었다.

  • 커넥션이 연결될 때마다 프로세스를 생성하는 방식 -> 메모리 부족 현상으로 이어짐
  • 확장성 -> 프로세스가 차지하는 리소스의 양이 늘어남.
  • 많은 커넥션 요청이 올때마다 굉장히 많은 컨텍스트 스위칭을 하여 CPU에 무리를 줌.

이러한 Apache의 구조적 한계를 극복하기 위해 나온 것이 바로 Nginx이다.


Nginx의 등장!

Nginx란 트래픽이 많은 웹사이트의 서버(WAS)를 도와주는 비동기 이벤트 기반구조의 경량화 웹 서버이다.
클라이언트로부터 요청을 받았을 때 요청에 맞는 정적 파일을 응답해주는 HTTP Web Server로 활용되기도 하고

Reverse Proxy Server로 활용하여 WAS의 부하를 줄일 수 있는 로드밸런서 역할을 하기도 한다.

 

그렇다면 Nginx는 어떠한 구조를 갖고 있길래 C10K문제를 해결할 수 있던 걸까??

바로 비동기 이벤트 기반구조를 갖기 때문이다.

 

Nginx의 비동기 이벤트 기반구조

비동기 이벤트 기반 구조는 대기중인 이벤트에 응답하고 이벤트를 비차단적으로 처리하여 동시에 많은 요청을 처리할 수 있게 한다.

이 구조는 Nginx의 가장 핵심이라고 할 수 있다. 이러한 구조는 다음과 같은 구성 요소로 구현된다.

 

하나의 프로세스(master process) / 하나 또는 다수의 스레드 (worker process)

Nginx는 하나의 master process가 하나 또는 다수의 worker process를 관리한다.

master process는 workeer process를 관리하는 일만 수행하고, worker process에서 사용자의 응답에 대응하는 방식을 취한다.

각각의 worker process에 대해서는 single thread 방식으로 동작여러 클라이언트 요청을 동시에 처리 수 있다.

 

Master Process = 구성 파일을 읽고 workeer process를 유지 및 관리
Worker Process = Single Thread로 구성되어 실제 사용자의 요청을 처리

 

 

즉, 모든 동시 요청은 전체 단위의 workeer process에 의해 처리되고, workeer process는 요청에 대한 결과를 master process로 보내고 master process는 해당 요청의 결과를 제공한다.

 

workeer process의 수는 "nginx.conf" 구성 파일의 "worker_processes" 지시어로 정의되며 고정된 수로 설정하거나 사용 가능한 CPU 코어 수에 따라 자동으로 조정되도록 구성할 수 있다.

 

이벤트 드리븐(event-driven) 프로그래밍

Nginx에서 connection을 형성하거나 제거하고 새로운 요청을 처리하는 것을 "이벤트(event)"라고 한다.

  1. event 들은 queue 형식으로 worker process에게 전달한다
  2. event 들이 quene에 담긴 상태에서 비동기 상태로 대기한다.
  3. worker process (단일 스레드)는 이 이벤트들을 queue에서 꺼내 처리한다.

이러한 방식을 작업이 완료 될 때까지 기다리지 않고 이벤트 큐에서 다음 이벤트를 처리하는 비동기 이벤트 드리븐 모델이라고 한다.

작업이 완료 될 때까지 기다리지 않고, 쉬지 않고 일을 하기 때문에 요청이 없을 때 프로세스를 방치 시키는 Apache보다 훨씬 효율적으로 자원사용이 가능하다.

 

I/O 멀티플렉싱

nginx는 I/O 멀티플렉싱 기술을 사용하여 동시에 많은 연결을 관리 할 수 있다.

 

비차단(non-blocking) 소켓

nginx는 비차단 소켓을 사용하여 입출력 작업을 수행하며, 클라이언트의 요청 및 응답을 지연 없이 처리할 수 있다.


Nginx의 장단점

 

장점

 

고성능

Nginx는 비동기 이벤트 기반 구조를 사용하여 매우 빠르고 효율적인 웹 서버 기능을 제공한다,

프로세스 간의 블로킹을 최소화하고 많은 요청을 동시에 처리할 수 있어 큰 트래픽에 대한 처리에 탁월하다.

 

높은 확장성

Nginx는 여러 프로세스를 사용하므로 수천 개의 동시 연결을 처리할 수 있다.

 

 

리버스 프록시 (Reverse Proxy)와 로드 밸런싱

"클라이언트 요청을 대신 받아 내부 서버로 전달"해주는 것 리버스 프록시라고 한다.

localhost:8080라고 하는 웹서버를 열어서 운영했다고 가정해보자.

이는 웹서버가 그대로 노출되어 있기 때문에 보안에 위험이 있다.

 

하지만 리버스 프록시를 사용하면 "클라이언트 -> nginx -> 웹서버"로 구성해서 사용자의 요청을 nginx가 대신 웹서버로 전달해주기 때문에 

해당 서버에 접속하는 서버 주소를 숨기고 프록시 서버의 주소만을 노출하여, 중요한 정보가 담겨져 있는 DB서버, 캐시 서버의 해킹을 방지할 수 있다.

 

로드 밸런싱

프록시 서버 트래픽 분산 기능 , 로드 밸런싱을 제공한다.

로드밸런싱이란 다수의 서버에 트래픽을 분산시켜 부하를 분산시키는 작업이다.

한 서버에 트래픽이 과도하게 몰릴 경우 해당 서버가 버티지 못하는 경우가 생길 수 있다.

Nginx는 지정된 리버스 프록시 서버에 트래픽을 분산시켜 트래픽이 과중하게 몰리는 경우를 방지할 수 있다.

 

 

단점

 

동적 컨텐츠 처리 한계

Nginx는 정적 파일에 최적화 되어 있어 동적 컨텐츠 처리에 한계가 있다.

하지만 백엔드 애플리케이션 서버나 API에 요청을 전달해 동적 컨텐츠를 처리하여 이러한 한계를 극복할 수 있다.

 

요청 기반이 아닌 연결 기반 처리

Nginx는 이벤트 기반 모델을 사용하여 웹 요청을 처리하는 데에 있어, 연결 기반 처리 방식을 사용하게 된다.

이러한 방식은 연결 성능을 최적화하더라도 개별 요청의 처리 속도가 느려질 수 있다.

이로 인해 특정 클라이언트의 연결에 많은 리소스가 할당되고, 이를 처리하는 동안 다른 클라이언트의 요청을 처리하는 데 있어 지연이 발생할 수 있다.

 

하지만 이러한 단점을 극복하기 위해 다음과 같은방법을 사용할 수 있다.

  • 로드 밸런싱 : 리버스 프록시로 동작하는 Nginx를 통해 여러 백엔드 인스턴스로 요청을 분산시키면서 고르게 나눌 수 있다.
  • Keep-Alive 연결 시간 제한 : Keep-Alive 연결에 대한 제한 시간을 설정하여 클라이언트와 서버 사이의 연결이 오랜 시간 동안 유지되지 않도록 실퇄를 줄일 수 있다.
  • 전송 속도 조절 : 전송 속도(limit_rate 지시문 사용)를 제한하여 고객 연결이 다른 연결에 영향을 줄 여지를 줄일 수 있다.
  • 워커 수 및 프로세스 관리 최적화 : Nginx 워커 프로세스 수를 조절하여 요청 처리량을 늘리거나 감소시킬 수 있다.

 

모듈 지원 제한

아파치와 달리 Nginx는 기본적으로 컴파일 시점에 모듈을 선택적으로 포함한다.

즉, 확장 또는 제거시 Nginx를 재컴파일 해야 한다.  이렇게 함으로써 Nginx는 더 가벼운 메모리 사용량과 높은 성능을 제공할 수 있다.

하지만 이 방식이 어떤 상황에서 유연성을 제한하는 요소가 될 수 있다.

 

초기 설정 복잡성

아파치 웹 서버보다 초기 설정이 비교적 복잡할 수 있다.

nginx의 구성 파일 구문 및 설정 옵션을 다루데 어려움을 겪을 수 있지만, 한 번 익숙해진다면 큰 문제가 되지는 않는다.


정리

구글 트랜드를 통해 Nginx와 Apache의 관심도를 비교한 결과를 보면 2021년도 12월 부터 Nginx에 대한 관심도가 크게 증가한 것을 볼 수 있다.

 

Apache Nginx
요청 당 스레드 또는 프로세스가 처리하는 구조 비동기 이벤트 기반으로 요청
CPU/메모리 자원 낭비 심함 CPU/메모리 자원 사용률 낮음
NginX보다 모듈이 다양 Apache에 비해 다양한 모듈이 없음
PHP 모듈 등 직접 적재 가능 많은 접속자들 대응 가능
안정성, 확장성, 호환성 우세 성능 우세
동적 컨텐츠 단독 처리 가능 동적 컨텐츠 단독 처리 불가능
Apache는 대규모 커뮤니티가 있으며 많은 지원이 있고 오랜 역사를 가진 만큼 안정성 또한 뛰어나다.
하지만 NginX는 성능, 속도 측면에서 우월하다.

 

Apache와 NginX는 모두 강력하고 유연한 웹서버로, 어떤 웹서버가 더 좋다 라는 결론을 내릴 수가 없다.

어떤 것을 사용할 지는 두 웹 서버의 특징과 요구사항을 고려해 선택될 것 이다.

 

Apache 정리

클라이언트 접속마다 Process 혹은 Thread 를 생성하는 구조이다.

1만명의 클라이언트로부터 동시접속 요청이 들어온다면 CPU 와 메모리 사용이 증가하고 추가적인 Process/Tread 생성비용이 드는 등 대용량 요청에서 한계를 보인다.

또한, Apache 서버의 프로세스가 blocking될 때 요청을 처리하지 못하고 처리가 완료될 때까지 대기상태에 있다. 

 

Nginx 정리

Nginx는 이벤트 드리븐 방식으로 동작한다.

한 개 또는 고정된 프로세스만 생성하고, 그 내부에서 비동기로 효율적인 방식으로 작업를 처리한다.

Apache와 달리 동시접속자 수가 많아져도 작업이 완료 될 때까지 기다리지 않고, 쉬지 않고 일을 하기 때문추가적인 생성비용이 들지 않아 효율적으로 자원 사용이 가능하다.