https://blog.naver.com/gi_balja/223028077537
🧐 Nginx란?
트래픽이 많은 웹사이트의 서버(WAS)를 도와주는 비동기 이벤트 기반구조의 웹 서버 프로그램이다.
"Nginx(엔진엑스)는 높은 성능, 확장성, 안정성을 자랑하는 현대적인 웹 서버입니다. 공식문서에서는 "고성능, 확장성, 고가용성을 갖춘 웹 서버, 역방향 프록시 서버, 그리고 웹 가속기"로 소개되며 HTTP 로드 밸런싱, 콘텐츠 캐싱 등의 다양한 기능을 제공합니다
Nginx는 단순히 정적 파일만 처리하는 서버가 아니라, 로드 밸런서와 같은 역할을 통해 대규모 트래픽 처리 및 다양한 서버 간의 부하를 분산하는 데 최적화된 도구입니다.
Web Server : 단순히 정적 파일 응답
WAS(Web Application Server) : 클라이언트 요청에 대해 동적 처리가 이뤄진 후 응답
📝 Nginx가 만들어진 배경
1995년 유닉스 기반으로 만들어진 최초의 웹서버 NCSA HTTPd가 있었다. 하지만 버그가 굉장히 많았다. 그래서 만들어진 것이 아파치 서버(Apache HTTP Server)이다.
초기 웹 서버와 Apache의 한계
1990년대 중반, 유닉스 기반 최초의 웹 서버인 NCSA HTTPd가 등장했지만, 안정성 문제로 인해 Apache HTTP Server가 대안으로 개발되었다. Apache는 프로세스 기반 아키텍처로 요청을 처리하며 확장성과 기능성 면에서 뛰어난 성능을 보였으나, 동시 연결 수가 급증하는 C10K 문제(10,000개의 동시 연결 처리)를 극복하기에는 한계가 있었다.
Apache 서버는 요청마다 새로운 프로세스를 생성하거나 미리 생성된 프로세스를 재활용하는 방식을 채택했지만, 이는 메모리 사용량 증가, CPU 부하 증가, 빈번한 컨텍스트 스위칭 등의 문제를 야기했다.
Nginx의 탄생
2004년, 이러한 한계를 해결하기 위해 비동기 이벤트 기반 아키텍처를 도입한 Nginx가 개발되었다. Nginx는 Apache와 함께 사용하도록 설계되었으며, 정적 파일 처리를 자체적으로 수행하고 동적 요청만 Apache에 위임함으로써 서버 부하를 효율적으로 줄였다.
Apache HTTP SERVER
Apache의 요청 처리 방식
Apache HTTP Server는 클라이언트 요청이 들어오면 새로운 프로세스를 생성하여 해당 요청을 처리한다. 이는 유닉스 계열 운영체제의 네트워크 커넥션 처리 모델을 그대로 따른 방식이다.
하지만 프로세스를 생성하는 데 시간이 오래 걸리는 단점이 있기 때문에, Apache는 요청이 들어오기 전에 프로세스를 미리 만들어 두는 PREFORK 방식을 채택했다.
- 클라이언트 요청이 발생하면 미리 생성된 프로세스를 바로 사용한다.
- 기존 프로세스가 모두 사용 중이라면 새로운 프로세스를 추가로 생성해 요청을 처리한다.
이러한 방식은 개발이 상대적으로 쉬운 구조를 제공하며, 다양한 기능을 확장할 수 있다는 장점이 있다.
Apache HTTP SERVER 확장성
Apache는 확장성이 뛰어난 서버이기 때문에 개발자들이 다양한 모듈을 만들어서 서버에 빠르게 기능을 추가할 수 있었다. 이 덕분에 동적 콘텐츠 처리와 같은 복잡한 작업도 Apache 내부에서 해결할 수 있어, 많은 웹 애플리케이션 환경에서 인기를 끌었습니다. 요청을 받고 응답을 처리하는 과정을 하나의 서버에서 해결하기 좋았다. 아파치 서버는 동적 컨텐츠를 처리할수 있게 되었다
C10K 문제
1999년부터는 서버 트래픽량이 높아져서 서버에 동시 연결된 커넥션이 많아졌을 때 더 이상 커넥션을 형성하지 못하는 문제가 생겼다.이를 C10K 문제(Connection 10000 Problem)라고 한다.
아파치 서버는 다음과 같은 문제점이 있었다.
- 커넥션마다 새로운 프로세스를 생성하고 유지하기 때문에, 동시 연결 수가 많아질수록 메모리 부족 문제 발생
- 다양한 기능과 확장성을 위해 리소스를 많이 사용하는 구조가 되어, 가벼운 요청 처리에는 비효율적
- 프로세스가 많아지면 컨텍스트 스위칭(프로세스 간 전환)이 잦아져 CPU 사용량이 급증.
즉, 수많은 동시 커넥션을 감당하기엔 아파치 서버의 구조가 적합하지 않았다.
Nginx + Apache HTTP SERVER
2004년, Apache HTTP Server의 한계를 극복하기 위해 NGINX가 개발되었는데, 초기에는 Apache와 상호 보완적으로 작동하도록 설계되었다. 두 서버는 각자의 강점을 살려 협력하며 사용되었는데, NGINX는 정적 콘텐츠를 처리하고 수많은 동시 연결을 효율적으로 관리하는 역할을 맡았고, Apache는 복잡한 동적 콘텐츠 처리에 집중할 수 있도록 지원했다.
📝 Nginx의 구조
Nginx 구조
Nginx는 마스터 프로세스와 워커 프로세스로 구성된 구조를 채택하여 높은 성능과 효율성을 제공한다. 마스터 프로세스는 설정 파일을 읽고 해석하며, 워커 프로세스를 생성하고 관리하는 역할을 한다. 또한, 워커 프로세스의 상태를 모니터링하면서 필요에 따라 재시작하거나 종료한다.
워커 프로세스는 클라이언트 요청을 실제로 처리하는 주체로, 비동기 이벤트 기반 모델을 활용한다. 각 워커 프로세스는 OS로부터 Listen 소켓을 할당받아 클라이언트 요청을 처리하며, 요청은 커넥션 형태로 유지되는데, 특정 Keep-Alive 시간 동안 연결 상태를 지속한다. 요청이 없는 경우에도 워커 프로세스는 기존 커넥션을 방치하지 않고, 새로운 요청이나 다른 커넥션의 작업을 처리함으로써 자원을 효율적으로 활용한다.
Nginx는 커넥션 관리와 요청 처리를 이벤트 단위로 나누어 관리한다. OS 커널은 이벤트를 큐(queue) 형태로 워커 프로세스에 전달하며, 워커 프로세스는 이를 단일 스레드로 비동기 처리한다. 또한, 처리 시간이 오래 걸릴 수 있는 작업에 대비해 스레드 풀(Thread Pool)을 지원한다. 워커 프로세스는 이러한 작업을 스레드 풀에 위임하여 다른 요청을 병행 처리하며, 지연으로 인해 전체 서버 성능이 저하되는 것을 방지힌다.
일반적으로 Nginx는 CPU 코어 수만큼 워커 프로세스를 생성하며, 각 코어에 프로세스를 분배하여 컨텍스트 스위칭을 줄이고 CPU 효율을 높인다. 이와 같은 구조는 Nginx의 핵심인 이벤트 기반 모델을 가능하게 하며, Apache와 비교했을 때 훨씬 효율적인 서버 자원 활용을 제공한다. 결과적으로 Nginx는 대규모 트래픽 환경에서도 안정적이고 고성능의 서버 운영이 가능하도록 설계되었다.
Nginx에서는 커넥션의 생성, 제거, 그리고 새로운 요청을 처리하는 과정을 "이벤트(event)"라고 부른다.
이벤트는 OS 커널이 큐 형식으로 워커 프로세스에 전달되며, 워커 프로세스는 큐에 있는 이벤트를 비동기적으로 처리한다. 각각의 워커 프로세스는 하나의 스레드로 이벤트를 처리하고, 여러 이벤트를 효율적으로 관리한다. Apache 서버의 경우 커넥션을 처리할 때 요청이 없다면 방치하는 반면, Nginx는 연결된 커넥션에 요청이 없을 경우 다른 커넥션을 처리하거나 새로운 커넥션을 형성하여 서버 자원을 보다 효율적으로 활용한다.
🧐 만약 큐에 담긴 요청중 하나가 시간이 오래 걸린다? Nginx는 스레드 풀(Thread Pool)을 사용해 해당 요청을 별도로 처리하고, 워커 프로세스는 다른 이벤트를 계속해서 처리할 수 있도록 한다. 이러한 방식은 서버의 성능을 최적화하는 데 중요한 역할을 한다.
Nginx에서 워커 프로세스는 보통 CPU 코어 수에 맞춰 생성되며, 이로 인해 각 코어가 담당하는 프로세스를 변경하는 횟수가 줄어들어 CPU의 컨텍스트 스위칭을 최소화한다. 이러한 구조는 Nginx가 채택한 이벤트 기반 모델(Event-Driven Model)의 핵심으로, 서버 자원을 효율적으로 활용하고 성능을 극대화할 수 있다.
Nginx의 장점은 뛰어난 효율적인 자원 관리와 높은 성능, 그리고 뛰어난 동시 처리 능력입니다. 이러한 특성 덕분에 Nginx는 많은 동시 연결을 효율적으로 처리할 수 있어 고성능 웹 서버나 로드 밸런서로 많이 사용됩니다. 또한, 이벤트 기반 처리 방식을 채택하여 서버 자원을 최소화하면서 빠르게 요청을 처리할 수 있습니다.
하지만 Nginx의 단점은 개발자가 직접 모듈을 만들거나 수정하는 것이 상대적으로 어렵다는 점이다. 이는 Nginx가 고도로 최적화된 구조를 가지고 있어, 새로운 기능을 추가하거나 수정하려면 깊은 시스템적 이해가 필요할 수 있기 때문이다.
이러한 한계를 극복하고 더 간편하게 확장성을 제공하려면 NGINX Plus를 고려하는 것이 좋은 선택이 될 수 있다. NGINX Plus는 상용 버전으로, 더욱 풍부한 기능과 향상된 기술 지원을 제공하며, 모듈 개발 및 설정을 더 직관적이고 수월하게 할 수 있다. 또한, 고급 로드 밸런싱, 웹 애플리케이션 방화벽, 실시간 모니터링 및 다양한 엔터프라이즈급 기능을 제공하여 Nginx의 기능을 더 확장하고 관리할 수 있는 효율적인 방법을 제시한다.(www.nginxkorea.co.kr)
📝 Nginx
개발자가 직접 모듈을 만들기가 까다롭다. ▶ NGINX 상용화 버전 고려
Nginx는 고도로 최적화된 아키텍처를 사용하고 있어, 새로운 기능을 추가하거나 기존 기능을 수정하는 데 기술적인 도전이 있을 수 있다. 그러나 Nginx는 여러 가지 장점이 있다. 첫 번째로, 프로세스를 적게 생성하므로 가볍고 효율적인 자원 관리를 가능하게 힌다. 적은 프로세스를 생성하는 구조는 시스템 자원을 절약하고, Nginx의 설정을 동적으로 바꿀 수 있게 해준다. 즉, 설정을 변경하더라도 서버를 재시작할 필요 없이 실시간으로 업데이트할 수 있다.
또한, Nginx는 동시 커넥션을 처리하는 능력이 뛰어나며, 최소 10배, 일반적으로는 100배에서 1000배까지 동시 커넥션을 처리할 수 있다. 동일한 커넥션 수일 때 처리 속도는 2배 향상되며, 이를 통해 고성능을 유지하면서 많은 트래픽을 효율적으로 처리할 수 있습니다. 이 모든 특성 덕분에 Nginx는 대규모 트래픽을 다룰 때 유리하고, 동적 설정 변경 기능도 제공하여 실시간으로 서버 환경을 유연하게 조정할 수 있습니다.
🧐 이런 동적 설정 변경은 언제 쓰나요?
Nginx가 여러 동시 커넥션을 관리하는 도중 뒷단에 서버가 추가되는 상황이 있다.
그 때 Nginx가 로드 밸런서의 역할을 담당하게 된다.
로드 밸런서는 요청을 여러 서버로 분산하는 작업을 수행하게 된다.
결국 동시 커넥션을 유지하여 기존 요청을 계속 처리하면서 뒷단에 서버를 추가할 수 있는 것이다.
Nginx는 이런 설정 변경을 초당 수십번을 해도 무리없이 커넥션을 관리하고 요청을 서버에 전달하게 된다.
성능 테스트 결과
동시 커넥션 수당 메모리 사용률
이 지표는 동시 커넥션 수당 메모리 사용률인데 Nginx는 동시 커넥션이 많아져도 메모리 사용률이 낮고 일정하지만
아파치 서버는 많이 사용하고 있다.
동시 커넥션 수에 따라 처리되는 초당 요청 수
동시 커넥션 수가 많아졌을 때 처리하는 초당 요청 수는 Nginx가 많고 아파치는 낮다. 최소 2배 이상 차이가 난다.
이 지표들은 Nginx가 커넥션 관리를 얼마나 잘하는지 보여준다.
Apache vs Nginx
https://news.netcraft.com/archives/2022/01/17/january-2022-web-server-survey.html
웹서버 1,2위를 다투고 있는데 이는 둘 다 장단점이 있기 때문이다.
22년 1월 nginx 32.88%, apache 24.25% 이다.
Apache
- 오랜 기간 업데이트로 다양한 OS에서 안정적
- 모듈을 추가할 수 있는 확장성
Nginx
- 웹 서버 보완(C10K 동시 커넥션 문제 해결)
- 성능 (윈도우에서 제대로 된 성능을 내지 못함)
NGINX 기능
- 웹 서버
- 로드 밸런서
- 웹 서버 가속기
- SSL 터미네이션 : 클라이언트와 https 통신하고, 서버와 http 통신하는 것
- 캐싱 : http 프로토콜을 사용하여 전달하는 콘텐츠를 캐싱할 수 있음, 한 번 서버에서 응답받은 것을 스스로 보관하고 클라이언트에 전달함.
- HSTS(HTTP Strict Transport Security)
- CORS 처리
- TCP/UDP 커넥션 부하 분산
- HTTP/2 등
📝 Q&A 공간
Q. NGINX는 정적 처리만 하는 서버가 아닌가요?
A. NGINX 기능 및 모듈을 이용해 다른 프로그램의 도움을 받지않는다고 가정한다면, NGINX는 정적처리만 하는 웹서버가 맞습니다.
하지만 NGINX 기능 및 모듈인 CGI 또는 프록시 기능을 사용한다면 동적 요청을 외부 프로그램에 전달하여 처리하므로 동적처리를 제공한다고도 볼 수 있습니다.
Q. "아파치 서버는 요청이 없다면 방치되던 프로세스에 비해 서버 자원을 효율적으로 쓰는 것을 알 수 있다." 라는 문장에서 주어가 아파치 서버가 아니라 NGINX 서버가 아닌가요?
A. 아파치 서버는 하나의 커넥션 연결 후 요청이 없으면 방치가 되는 반면, NGINX는 요청이 없으면 다른 커넥션 요청을 처리하거나 새로운 커넥션을 만들어 처리하므로 아파치 서버에 비해 NGINX는 서버 자원을 효율적으로 사용합니다. 라는 의미로 적어놓은 것입니다.
제가 애매모호하게 적어놓은 부분이 있어서 글 본문에는 수정하였습니다.
Q. "Nginx의 설정을 동적으로 바꾸는게 가능하다" 이 말은 무슨 의미인가?
A. NGINX는 설정을 바꾸면 마스터 프로세스가 거기에 맞는 새로운 워커 프로세스를 생성하여 이후 요청들은 새로운 워커 프로세스에서 처리합니다. 기존 커넥션이 연결된 기존 워커 프로세스에서는 새로운 커넥션은 형성되지 않고 기존 커넥션이 처리가 다되면 알아서 종료시킵니다. 이 때문에 NGINX는 설정을 동적으로 바꾸는게 가능하다 라고 적었습니다.
https://ko.wikipedia.org/wiki/Nginx
https://www.youtube.com/watch?v=6FAwAXXj5N0&t=651s
https://www.youtube.com/watch?v=ZJpT-Wa-pZ8&t=342s
https://www.aosabook.org/en/nginx.html
'F5 Solution > NGINX' 카테고리의 다른 글
[NGINX KOREA] 누구도 예상 못한 NGINX의 무한 변신, 당신의 NGINX 스토리를 기다립니다 (0) | 2024.12.11 |
---|---|
HashiCorp Vault를 사용하여 NGINX에서 SSL 개인 키 보호 (0) | 2024.11.18 |
CBDC(중앙은행 디지털 화폐)와 NGINX (0) | 2024.11.18 |
JWT가 탈취되면 어떻게 될까? (0) | 2024.11.14 |
100배 빠른 속도? 이론상 가능성 (0) | 2024.11.12 |