Nginx란 트래픽이 많은 웹사이트의 서버(WAS)를 도와주는 비동기 이벤트 기반구조의 경량화 웹 서버 프로그램입니다. 클라이언트로부터 요청을 받았을 때 요청에 맞는 정적 파일을 응답해주는 HTTP Web Server로 활용되기도 하고, 또는 Reverse Proxy Server로 활용하여 WAS의 부하를 줄일 수 있는 로드밸런서 역할을 하기도 합니다.
단순히 정적 파일을 응답
클라이언트 요청에 대해 동적인 처리가 이뤄진 후 응답
Apache는 새로운 클라이언트 요청이 들어오면 새로운 프로세스나 쓰레드를 생성하여 처리했다. 하지만 프로세스를 생성하는 시간이 오래 걸리기 때문에 요청이 들어오기 전 프로세스를 미리 생성하는 PREFORK 방식을 사용한다. 만약 만들어 놓은 프로세스가 모두 할당되었다면 추가로 만든다.
이런 구조는 확장성이 좋아 개발하기 쉽다는 장점이 있다. 모듈이라는 개념으로 수많은 기능을 덧붙일 수 있다. 이 모듈을 통해 다른 프로그램과의 연동도 가능하다.
하지만 1999년대부터 사용자 수가 급격히 늘어나면서부터 문제가 생기기 시작했는데 서버에 동시에 연결된 커넥션이 많아졌을 때 더 이상 커넥션을 형성하지 못하는 C10K(Connection 10000 Problem) 현상이 일어나기 시작했다.
이 C10K 현상은 아파치 서버의 구조가 주 문제였다.
커넥션이 형성될 때마다 프로세스가 할당되기 때문에 메모리가 부족
위에서 말한 확장성이라는 장점이 오히려 단점이 되어 무거운 프로그램이 되었다.
많은 커넥션 요청이 들어오면 CPU는 계속해서 프로세스를 바꿔가며(Context Switching) 일해야 됐기 때문에 CPU에 부하가 계속해서 증가했다.
트래픽이 증가하면서 Apache의 한계를 극복하기 위해 Nginx가 등장하였다. Nginx는 Event-Driven 구조로 동작하기 때문에 한 개의 프로세스만 생성하여 사용하고 비동기 방식으로 요청들을 동시적으로 처리할 수 있다.
Event-Driven
자동으로, 혹은 정해진 순서에 따라 발생하는 게 아니라 어떤 일에 대한 반응으로 일어나는 구조

Nginx는 하나의 master process와 다수의 Worker Process로 구성될 수 있다. master process는 설정 파일을 읽고 설정에 맞게 worker process를 생성한다. 이 worker process가 생성될 때 각자 지정된 listen 소켓을 배정받는다. 그리고 그 소켓에 클라이언트의 여러 요청들을 받고 처리할 수 있다. 이런 connection 형성, 제거, 새로운 요청을 처리하는 것을 event라고 한다.

이 event들을 OS 커널이 queue 형식으로 worker process에게 전달해 준다. 이 event는 queue에 담긴 상태에서 worker process가 처리해 줄 때까지 비동기 방식으로 대기하다가 worker process가 하나의 쓰레드로 event를 꺼내 처리한다.
높은 성능과 적은 메모리
Nginx는 비동기 I/O 처리 방식을 사용하여 높은 성능를 제공합니다. 이를 통해 대규모 웹사이트에서도 빠른 응답 시간을 보장할 수 있습니다. 또한 Nginx는 적은 메모리 사용량으로도 높은 성능을 제공합니다. 이를 통해 서버 운용 비용을 절감할 수 있습니다.
리버스 프록시(Reverse Proxy) 사용이 가능
프록시는 인터넷 접속을 할 때 보안상의 문제로 직접 통신을 주고받을 수 없을 때 그 사이의 중계기로서 대리로 통신을 수행하는 기능입니다. 리버스 프록시는 인터넷과 백엔드 그 사이에 있는 서버 영역을 말합니다. 예를 들어, WAS로 사용하고 있는 서버가 여러대가 있으면 클라이언트가 1, 2로 접근하면 1은 A서버, 2는 B서버로 전달하여 요청에 해당하는 웹 서버로 길을 분배할 수 있습니다. 이를 로드밸런싱이라고 합니다.
데이터 압축
클라이언트가 보내는 요청이 Text일 때 gzip을 사용하여 해당 데이터를 압축시킬 수 있습니다.
비동기 처리
Nginx는 이벤트 루프 방식을 사용하여 높은 성능을 제공합니다. 이를 통해 동시에 여러 요청이 들어왔을 때도 많은 트래픽을 동시에 처리할 수 있어 빠른 응답시간을 보장합니다.
이벤트 루프 방식
이벤트 루프(event loop)방식은 주로 비동기적인 이벤트 처리를 위해 사용되는 프로그래밍 패턴입니다. 주로 이러한 패턴은 이벤트 기반의 시스템 또는 네트워크 프로그래밍에서 많이 사용됩니다.
- 이벤트 큐(Event Queue): 발생한 이벤트들이 순서대로 저장되는 자료구조입니다.
- 이벤트 루프(Event Loop): 이벤트 큐에서 이벤트를 가져와 처리하는 루프입니다. 이벤트 루프는 주로 단일 스레드에서 동작하며, 이벤트를 처리하고 해당 이벤트에 대한 적절한 작업(콜백 함수 호출, 다른 이벤트 발생 등)을 수행합니다.
- 이벤트 핸들러(Event Handler): 이벤트를 처리하는 코드 블록 또는 함수입니다. 이벤트가 발생하면 해당 이벤트에 대한 처리를 담당하는 이벤트 핸들러가 호출됩니다.