이전 글에서는 include 디렉티브로 설정 파일을 구조적으로 분리하는 방법을 살펴봤다.
이번 글에서는 한 발 더 나아가, Nginx가 실제로 얼마나 많은 요청을 동시에 처리할 수 있는지를 결정하는 Process Model 설정을 살펴본다.
nginx.conf의 최상단에서 마주치는 worker_processes와 worker_connections가 바로 그 핵심이다.
Nginx의 Process 구조
Nginx는 실행되면 크게 두 종류의 프로세스로 동작한다.

Master Process는 설정 파일을 읽고, Worker Process를 생성·관리하는 관리자 역할을 한다. 실제 클라이언트 요청은 직접 처리하지 않는다.
Worker Process가 실제로 클라이언트의 요청을 받아서 처리한다. 클라이언트 요청은 Master를 거치지 않고 Worker에게 직접 전달되며, 각 Worker는 독립적인 프로세스로 동작하면서 이벤트 루프(Event Loop) 방식으로 여러 연결을 비동기적으로 처리한다.
worker_processes — Worker 프로세스 수 설정
Nginx의 메인 설정 파일인 nginx.conf 파일에서 worker_processes는 Nginx가 몇 개의 Worker 프로세스를 띄울지 결정한다.
설정 파일 작성은 아래와 같은 방식으로 이뤄진다.
# nginx.conf (Main Context)
worker_processes 4; # Worker를 4개 생성
worker_processes auto; # CPU 코어 수에 맞게 자동 설정 (권장)
일반적으로는 auto로 코어 수에 맞게 설정하는데
그 이유는 다음과 같은 것들이 있다.
왜 CPU 코어 수에 맞추는가?
Nginx의 Worker Process는 단일 스레드로 동작한다. 즉, Worker 하나가 CPU 코어 하나를 점유한다. 코어보다 Worker가 많으면 컨텍스트 스위칭(Context Switching) 비용이 발생하고, 적으면 코어가 놀게 된다.
따라서 특별한 경우( 리소스를 분할해야하는 ex, 코어가 8개인데 nginx에 4개를 할당하고 같은 서버에서 다른 app을 구동하는 경우, 운영 환경과 동일하게 맞춰서 테스트 환경을 갖추는 경우 등 )가 아니라면
Worker 수 = CPU 코어 수가 가장 효율적이며, auto로 설정하면 Nginx가 알아서 맞춰주기에 auto로 설정하는 것이 권장된다.
worker_connections — Worker당 최대 연결 수
events {
worker_connections 1024;
}
worker_connections는 Worker 프로세스 하나가 동시에 처리할 수 있는 최대 연결 수다.
events { } 블록 안에 선언한다는 점이 특징을 지녔으며, 4개의 워커를 기준으로 1024연결이 가능하도록 한다면, 동시에 4096 연결이 가능하다.
하지만, Nginx를 리버스 프록시로 사용하는 경우 동시 접속에 대한 계산이 달라진다.
리버스 프록시 환경에서의 연결 수
일반적인 정적 파일 서버라면 클라이언트와 Nginx 사이의 연결만 고려하면 된다. 하지만 Nginx를 리버스 프록시로 사용하는 경우에는 연결 구조가 달라진다.

위와 같은 리버스 프록시 환경에서 클라이언트 요청 하나를 처리하기 위해서는 연결이 2개가 필요하다.
- 연결 1 — 클라이언트 ↔ Nginx Worker
- 연결 2 — Nginx Worker ↔ 백엔드 서버
즉, Worker의 worker_connections 중 클라이언트 요청 하나당 연결 2개가 소비된다.
따라서 리버스 프록시 환경에서의 실제 최대 동시 요청 수는 절반이 된다.
리버스 프록시 최대 동시 요청 수 = (worker_processes × worker_connections) / 2
앞의 예시(4워커 × 1024) 기준으로 다시 계산하면,
(4 × 1024) / 2 = 2,048
OS 레벨 제한도 함께 확인해야 한다
worker_connections 값을 아무리 높게 잡아도, OS가 허용하는 파일 디스크립터(File Descriptor) 수를 넘을 수 없다.
이 개념을 이해하지 못하면 설정은 했는데 실제로는 연결이 막히는 상황을 만나게 된다.
파일 디스크립터(File Descriptor)란?
Linux/Unix 계열 OS에서는 모든 I/O 자원을 "파일"로 추상화한다. 실제 파일뿐만 아니라 네트워크 소켓, 파이프, 디바이스 등도 모두 파일처럼 다룬다.
파일 디스크립터(fd)는 프로세스가 이런 I/O 자원을 열었을 때 OS가 부여하는 정수형 식별자다. 프로세스는 이 번호를 통해 해당 자원에 접근한다.
프로세스가 자원을 열면 → OS가 fd 번호를 부여
fd 0 → 표준 입력 (stdin)
fd 1 → 표준 출력 (stdout)
fd 2 → 표준 에러 (stderr)
fd 3 → 소켓 연결 1 ← Nginx가 여기서부터 사용
fd 4 → 소켓 연결 2
fd 5 → 파일 열기
...
Nginx에서 클라이언트 연결은 내부적으로 소켓(Socket)으로 처리되는데, 소켓도 fd 하나를 소비한다. 즉 동시 연결이 늘어날수록 Nginx Worker가 점유하는 fd 수도 그만큼 늘어난다.
fd 제한의 두 가지 계층
여기서 헷갈리기 쉬운 부분이 있다. Linux의 fd 제한은 사실 두 단계로 나뉜다.
① 시스템 전체 제한 (file-max) ← OS 전체 fd 총합 한도
└── ② 프로세스별 제한 (ulimit -n) ← 프로세스 하나당 한도
① file-max — 시스템에서 동시에 열 수 있는 fd의 총합 한도다. 아래 명령으로 확인할 수 있다.
cat /proc/sys/fs/file-max
# 예시: 1609904
이 값은 서버 메모리에 비례해 자동으로 설정되며, 보통 수백만 단위로 크게 잡혀 있다. 일반적인 서버 운영 환경에서 이 한도에 걸리는 경우는 거의 없다.
② ulimit -n — 프로세스 하나가 열 수 있는 fd의 한도다. Nginx Worker도 결국 하나의 프로세스이므로 이 제한을 그대로 받는다.
ulimit -n
# 기본값: 1024
문제는 바로 여기서 생긴다. file-max는 충분히 크더라도, 프로세스별 ulimit 기본값은 보통 1,024로 낮게 설정되어 있다.
worker_connections 10240으로 설정해도, Worker 프로세스의 ulimit가 1,024라면 실제로는 1,024개에서 막혀버린다.
worker_rlimit_nofile - 프로세스별 ulimit를 Nginx에서 올리기
worker_rlimit_nofile은 Nginx Worker 프로세스의 ulimit를 nginx.conf에서 직접 상향하는 디렉티브다.
file-max(시스템 한도)를 건드리는 게 아니라, 그 안에서 Worker 프로세스 하나의 한도를 올리는 것이다.
file-max (1,609,904) ← 시스템 한도 — 이건 못 넘음
└── Worker 프로세스 ulimit 기본값: 1,024 worker_rlimit_nofile 설정 후: 65,535 ← 이 범위 안에서 상향 가능
└── worker_connections: 10,240 ← ulimit 이하로 설정
예시
worker_processes auto;
worker_rlimit_nofile 65535; # Worker 프로세스의 ulimit를 65,535로 상향
events {
worker_connections 10240; # 반드시 worker_rlimit_nofile 이하로 설정
}
따라서, worker_connections는 반드시 worker_rlimit_nofile 이하여야 한다.
이에 아래와 같은 설정의 크기 관계를 지니게 될 것이다.
worker_connections ≤ worker_rlimit_nofile ≤ file-max
설정 전 확인 순서
따라서 요청 처리량의 관점에서 Nginx의 연결 수와 처리량을 계산하여 설정하기 위해서는 아래와 같은 순서에 따라 확인이 필요할 것이다.
# 1. 시스템 전체 fd 한도 확인 (보통 충분히 큼)
cat /proc/sys/fs/file-max
# 2. 프로세스별 ulimit 확인 (이게 실질적인 병목)
ulimit -n
# 3. ulimit가 낮다면 nginx.conf에서 worker_rlimit_nofile로 상향
# worker_rlimit_nofile 65535;
# 4. worker_connections는 그 이하로 설정
# worker_connections 10240;
# 5. 설정 적용
nginx -t && nginx -s reload
# 리버스 프록시인 경우 연결 수를 x2로 고려할 것
실전 설정 예시
소규모 서버 (2코어, 정적 파일 서버)
worker_processes 2;
events {
worker_connections 1024;
}
# 최대 동시 연결: 2 × 1024 = 2,048
중규모 서버 (4코어, 리버스 프록시)
worker_processes auto; # 4코어 → Worker 4개
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
}
# 최대 동시 연결: 4 × 4096 = 16,384
# 리버스 프록시 기준 실제 처리 요청: 8,192
고성능 서버 (8코어, 대용량 트래픽)
worker_processes auto; # 8코어 → Worker 8개
worker_rlimit_nofile 65535;
events {
worker_connections 10240;
use epoll; # Linux 환경에서 고성능 I/O 이벤트 모델 명시
multi_accept on; # 한 번에 여러 연결 수락
}
# 최대 동시 연결: 8 × 10240 = 81,920
'Nginx' 카테고리의 다른 글
| 네트워크 전송 관점에서 최적화를 위한 압축 설정 템플릿 (0) | 2026.05.21 |
|---|---|
| Nginx 성능 최적화 설정과 기본 템플릿 (0) | 2026.05.16 |
| Nginx include 디렉티브 - 설정 파일 분리와 구조화 (0) | 2026.05.12 |
| Nginx의 계층 구조와 상속 및 재정의 방식 (0) | 2026.05.10 |
| Nginx의 설정파일 구성 방법과 원리( .conf 파일 ) (0) | 2026.05.10 |
댓글