요즘 대부분의 백엔드 개발자가 갖춰야 할 기본 Skill 중에 하나가 Nginx이다. 최근 회사에서 Nginx를 다뤄볼 수 있는 경험을 줘서, Nginx가 무엇인지 그리고 실제 어떻게 사용하는지 알 수 있었다.
어떻게 적용했는가를 기재해보기 전에, Nginx에 대해 이론적으로 공부했던 것 중 중요하게 생각했던 것을 끄적여 본다.
⁉️ Nginx 공부 전 알아야 할 CS
- 클라이언트
- 서비스를 이용하기 위해 네트워크를 통해 요청을 보내는 주체
- 웹 개발 영역에서 보통 클라이언트라 하면 크롬, 사파리, 익스플로러 등 웹 브라우저를 의미
- 웹 서버
- 클라이언트의 요청에 따라 HTML, CSS, JS, 이미지 파일과 같은 정적 파일을 응답하여 제공하는 소프트웨어
- HTTP 프로토콜을 사용해 클라이언트와 통신
- 대표 : Nginx, Apache 등
- WAS
- 클라이언트 요청에 대해 동적인 처리를 담당하는 영역
- 웹 서버와 달리 애플리케이션 로직을 실행할 수 있도록 구성
- 대표 : Tomcat, JBoss 등

- 웹 서비스 동작 방식
- 요청 : 클라이언트 > 웹 서버 > WAS > DB
- 응답 : DB > WAS > 웹 서버 > 클라이언트
- 웹 서버 사용 이유
- WAS 부담 줄여주기 위해 (정적 파일을 웹 서버가 처리해줌)
- 보안 기능 제공 (SSL/TLS)
- 높은 성능 제공
- 비동기 처리 방식 사용해 높은 성능 제공
- 이벤트 기반, 멀티 프로세싱, 스레드 풀 등의 기술 사용 → 수천 대의 클라이언트 요청을 동시에 처리
⁉️ Nginx를 사용하는 이유
Nginx를 사용하는 이유는 여러가지가 있지만, 간단명료하게 정리하면 아래와 같다.
정적 파일 제공해 주는 웹 서버로 활용되기도 하고 프록시 서버 및 로드밸런서로 활용

- ‘Reverse Proxy(리버스 프록시)’를 통한 로드 밸런싱
- Port Proxy
- Path Proxy
- 예시
- 80/irish → 8000
- 80/irish1 → 8001
- 80/irish2 → 8002
- 높은 성능과 적은 메모리 사용
💥 Nginx vs Apache Web Server
Web Server에서 1,2위를 다투는 것이 Nginx와 Apache Web Server이다. 참고로, Apache Web Server가 Nginx보다 먼저 세상에 나왔다. 이 둘의 차이점은 무엇일까?
- Apache Web Server
- 등장 : 인터넷 보급이 활발하지 않은 시대에 등장
- 중점 : 안정성, 확장성
- 단점
- 아파치의 구조는 수많은 동시 커넥션을 처리하기에는 부적합(예: C10K)
- 이유 : 인터넷 보급이 활발하지 않은 시대에 등장했기 때문에, 수많은 프로세스를 생성하는 것에 한계가 존재
- Nginx
- 등장 : 트래픽이 증가하면서 Apache의 한계를 극복하기 위해 Nginx가 등장
- 중점
- 동작 원리 : Nginx는 Event-Driven 구조로 동작하기 때문에 한 개의 프로세스만 생성하여 사용하고 비동기 방식으로 요청들을 동시적으로 처리
✏️ Nginx의 구조

- 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를 꺼내 처리함
- 이렇게 되면 worker process가 쉬지 않고 계속해서 일을 하기 때문에 자원을 효율적으로 사용 가능(apache는 요청이 없다면 프로세스가 방치됨)
- 시간이 오래 걸리는 작업 같은 경우 Thread Pool에 event를 위임하고 큐 안의 다른 event를 처리함

- 이러한 worker process는 보통 CPU의 코어 개수만큼 생성하기 때문에 Context Switching 사용도 줄일 수 있음
- 하지만 개발자가 기능 추가를 시도했다가 돌아가고 있는 워커 프로세스를 종료하게 되면 해당 워커 프로세스가 관리하고 있던 커넥션과 관련된 요청을 더 이상 처리할 수 없게 되는 문제가 생김
- 따라서, Nginx는 개발자가 직접 모듈을 만들기가 까다롭다는 단점이 존재
💯 Nginx의 장점
- 동시 커넥션 양 최소 10배 증가(일반적으로 100 ~ 1000배 증가)
- 동일한 커넥션 수일 때 속도 2배 향상
- 동적 설정 변경
👍🏻 Nginx의 핵심 기능
리버스 프록시(Reverse Proxy)

- 클라이언트 요청을 대신 받아 내부 서버로 전달해 주는 것을 리버스 프록시라고 하는데 서버 정보를 클라이언트로부터 숨겨줌

- 예를 들어, 위처럼 구성하여 /로 요청 시 3000번 포트로 매핑
- /api로 요청하면 8080번 포트로 매핑
로드밸런싱(Load Balancing)

- 하나의 서버에서 받는 요청을 여러 대의 서버가 분산 처리할 수 있도록 요청을 나누어 주어 성능, 확장성 및 신뢰성을 향상시킬 수 있음
캐싱(Caching)

- 클라이언트가 요청한 내용을 캐싱 하여 같은 요청이 오면 캐시에 저장된 내용을 전송해 전송 시간을 절약할 수 있고 불필요한 외부 전송을 막을 수 있음
👀 느낀점
회사에서 내가 투입된 프로젝트에서는 Nginx와 같은 것을 사용하지 않았다.(Apache Web Server도 사용하지 않았다.)
[클라이언트 / WAS(Tomcat) / DB(Oracle)]로만 이루어져 있었다.
하지만, Nginx를 공부하게 되면서 내 프로젝트를 [클라이언트 / Web Server(Nginx) / WAS(Tomcat) / DB(Oracle)] 로 구성해보는 것이 어떨까 생각해봤다.
물론, Nginx를 적용하기 위해서는 어떤 것을 reverse proxy를 하여 연결을 해줄 것인가를 먼저 생각해봐야 할 것이다.
일단 간단히 생각을 해봤을 때에는, 일반 User가 데이터에 접근하는 것은 3000(React의 index.html)으로, Admin이 관리자 페이지에 접근하는 것은 8080로 port proxy해주는 것이 어떨까라는 생각을 해봤다.
다음에는 실습한 것을 위주로 Nginx 포스팅을 해보겠다.
🌐 Reference