Nginx

Nginx의 핵심적인 개념

_Jin_ 2026. 5. 7.

Nginx란?

 

Nginx는 (1) 웹 서버 / (2) 리버스 프록시 / (3) 로드 밸런서 / (4) HTTP 캐시 등의 기능을 제공해주는 소프트웨어로 23년 기준으로 전 세계 가장 인기있는 웹서버 중 하나로 점유율 1위에 위치하여 사용되는 소프트웨어이다. 

 

Nginx 사용 이유

그렇다면 이처럼 Nginx가 웹서버로 가장 많이 사용되는 이유는 무엇일까?

해당 부분은 C10K (connection 10,000)문제에 기인하여 찾아볼 수 있다.

 

C10K 문제 관련 글(링크)

더보기
https://oliveyoung.tech/2023-10-02/c10-problem/

 

Apache  VS  NGINX

위의 C10K 문제는 쉽게 말하면, 어떻게 동시에 1만명이 접속 가능한 서버를 만들 것인가에 대한 문제이다.

해당 문제가 등장했던 시기에 주로 사용하던 웹서버는 Apache 서버였다.

 

 

Apache

그리고 Apache 웹 서버는 아래와 같은 방식으로 작동한다.

 

Apache 서버는 연결 하나당 프로세스 혹은 스레드 하나를 할당하여 요청에 대한 응답을 처리한다.

즉 요청이 들어오면 새로운 프로세스를 만들거나 미리 만든 POOL에서 하나씩 꺼내 요청에 따라 할당하여 과정을 진행한다.

 

해당 방식이 지닌 문제점은 다음과 같은 3가지 정도의 명확한 문제를 지닌다. 

  • 메모리 문제
  - 메모리 하나당 대략 2~10mb 사용한다고 고려하면, 20GB가 필요하게 된다. 
    C10K 문제가 도출되었던 1999년도에는 물리적 하드웨어나 비용적 측면에서 감당하기 어려운 사항이었다.

 
  • 컨텍스트 스위치 비용
  - CPU는 한번에 하나의 프로세스만 실행할 수 있는데, 프로세스가 1만개라면, CPU가 이 1만개의 프로세스를 컨텍스트        스위칭을 통해서 처리해야한다. 그리고 컨텍스트 스위칭은 스위칭을 할 때마다 현재 상태 저장과 더불어 다른 프로세스        상태를 불러오는 과정이 동반된다. 이는 오버헤드가 비대를 유발한다. 따라서 스위칭하는 비용이 커져 비효율적이다.

 
  • 프로세스 생성 비용 및 작업 비효율
  - 프로세스를 생성하기 위해서는 Fork 시스템 콜을 통해 부모 프로세스의 메모리 공간을 복사하고 파일 디스크립터도 복        사하는 과정이 필요하다. 그리고 이는 꽤 무거운 작업으로 요청이 들어올 때마다 해당 과정을 진행하면 시스템은 당연하      게도 느려진다. 또한 이렇게 생성된 프로세스들은 대부분 아무것도 안하고 기다리는 시간들이 대부분을 차지할 것이다.
    따라서 실질적으로 CPU를 10%도 사용하지 않으면서 프로세스만 잔뜩 떠 있는 상황을 초래한다. 

 

위와 같은 문제들이 발생하기에 해당 문제들을 해결할 수 있는 NGINX가 인기를 얻게 된 것이다 .

 

Nginx

Nginx는 Apache가 해결하지 못하는 문제들을 다음과 같은 간단한 작동원리에 따라 해결한다. 

 

연결마다 프로세스를 만드는 것이 아닌 하나의 프로세스가 여러 연결을 처리한다.

 

이와 같은 방식으로 구동되는 Nginx 웹 서버는 아래와 같은 방식으로 작동된다. 

 

Nginx는 워커 프로세스 몇 개만으로 수만 개의 연결을 처리하도록 구성되었다.

이것을 가능하게 만드는 핵심적인 개념은 기다리지 않는 것이다. 

 

그리고 이를 cs적 언어로 표현하자면, 비동기 논블록킹 개념 기반의 아키텍쳐(이벤트 기반 아키텍쳐)인 것이다. 

결과적으로 1만개의 연결 요청에 대해서 Apache가 20GB의 메모리가 필요했다면 Nginx는 연결 요청 수 만큼의 프로세스를 생성할 필요가 없어진다.

따라서 100Mb 정도로도 충분해질 수 있다. 

그리고 컨텍스트 스위칭 비용도 급격하게 줄어든다. 워커가 4개면 4개 사이에서 스위칭이 이뤄지면 되기 때문이다.

 

이로써 정적 파일 기준으로 Nginx는 Apache에 비해 대략 3배 가까이 빠르고 메모리 사용량도 10분의 1 수준으로만 사용하여 처리가 가능해진다. 

즉, 많은 동시 접속이 필요하거나 리버스 프록시, 로드 밸런싱이 필요한 경우 등 Nginx가 좋은 선택지에 해당된다. 

 

 

Nginx 역할

 

정적 파일 서빙

Nginx는 HTML이나 CSS, JS, 이미지 파일과 같은 이런 정적 파일 등을 클라이언트에게 전달하는 웹서버 역할을 한다.

Nginx는 정적 파일 서빙에 매우 강력하다. 

(파일을 메모리에 캐싱하고 send file 시스템 콜을 통해서 커널에서 직접 네트워크로 데이터를 전송하기 때문)

 

 

리버스 프록시

클라이언트와 백엔드 사이 리버스 프록시로 중계자 역할 기능을 수행할 수 있다.

 

 

로드 밸런싱

트래픽 증가에 따라 서버의 숫자를 늘릴 수 있는데, Nginx가 이 서버들의 트래픽 분산 기능을 담당할 수 있다.

분산 정책에 대해 라운드 로빈으로 순서대로 보내거나 리스트드 커넥션으로 연결이 적은 쪽으로 최대한 분산한다거나

Ip Hash와 같이 같은 Ip는 항상 같은 서버로 보내는 등 다양한 알고리즘을 지원해준다.

그리고 이러한 기능은 MSA 환경에서 API Gateway 역할도 가능하게 만들어준다.

 

SSL 터미네이션

Https에 관련된 암호화나 복구화, 비대칭 키에 대한 것들을 Nginx에서 처리 가능하다. 

백엔드의 관점에서 이러한 Nginx의 기능은 아키텍쳐 관점에서 암호화 같은 기능을 추상화하여 불필요한 처리 로직을 감소시킨다.

 

 

Nginx 내부 구조(이벤트 기반)

 

위의 다이어그램이 Nginx가 작동하는 핵심 원리이다. 

비동기 논블로킹으로 작동되는 방식을 나타낸다.

 

그리고 이를 효율적으로 처리하기 위해서는 운영체제 레벨에서의 도움도 당연히 필요하게 된다. 

 

예를 들어, 리눅스 기준으로 ePool와 같은 기능을 사용하여 커널단에서 해당 소켓들을 감시하는 것에 대한 요청을 Nginx가 등록을 하고 커널이 관련된 이벤트가 발생할 떄만 알려준다. 

Nginx 입장에서는 이를 통해 해당 커널을 매번 확인할 필요가 없어지는 것이다. 

단지 알림을 받으면 알림 받은 소켓만 처리하는 것이다. ( 사실상 수만 개의 소켓을 감시해도 부하가 없다는 것이다. )

 

 

Nginx 내부 구조(프로세스)

 

 

한편, Nginx를 실행하면 기본적으로 Master 프로세스와 Worker 프로세스가 생성되는데,

Master 프로세스는 관리자 역할로 설정 파일을 읽고 검증하고 워커 프로세스를 생성하는 역할을 한다.

즉, 요청을 처리하기 위한 프로세스가 아닌 관리를 위해 존재하는 프로세스이다.

 

그리고 요청을 처리하는 프로세스는 Worker 프로세스이다. 실질적 일꾼인 셈이다.

워커 프로세스 숫자 조절도 가능한데, 이는 상황에 따라 다르지만, 일반적 기준은 CPU 코어 수와 동일하게 하는 것이 권장된다. 

이처럼 코어수만큼 설정하는 이유는 각 워커가 하나의 코어를 점유하면 컨텍스트 스위칭 비용이 최소화 되기 때문이다.

만약 워커가 코어보다 많다면 CPU가 워커 사이클을 왔다갔다 해야 하는 상황이 벌어지다보니 오히려 성능이 안 좋아질 수 있다.

 

 

Nginx 의 요청 처리

 

 

Nginx는 하나의 요청에 따른 처리 방식에 대해 전체적인 사이클을 확인해보자.

 

먼저 TCP 프로토콜로 연결을 수립한다.

그리고 HTTP 헤더를 파싱하여 메타 정보를 추출하여,

어떤 Server 블록으로 처리할지 정한다. (하나의 Nginx에서 여러 도메인을 호스팅할 수 있기 때문에)

 

이어서 location이라는 관점을 통해 URI를 확인하고 어떤 location 블록으로 처리할지 결정한다.

(예를 들어 api로 시작하면 백엔드로 프록시하고 static이면 정적 파일을 반환하는 방식 등)

 

다음에는 각 지정된 처리방식에 따라 처리하여 응답의 과정에 도달한다.

마지막으로는 연결에 대한 설정을 관리한다. 

Keep-Alive에 대한 설정에 따라서 연결 유지에 대한 지속성을 결정한다. 

 

댓글