Nginx는 무엇이고 왜 사용할까?
What is Nginx and Why use?
Nginx는 웹서버 점유율 1등으로 네이버, 카카오, 깃허브, 넷플릭스 등 다양한 곳에서 사용하고 있다. 어떻게 Apache를 제치고 Nginx가 많이 사용하게 되었는지 알아보자
Nginx
Nginx는 비동기 이벤트 기반 구조의 경량 웹 서버이다. 정적 파일 제공해 주는 웹 서버로 활용되기도 하고 프록시 서버 및 로드밸런서로 활용되기도 한다.
Nginx vs Apache
Apache와는 어떤 차이점이 있길래 Apache를 제치고 1등이 되었을까?
Apache 동작 방식
Apache는 새로운 클라이언트 요청이 들어오면 새로운 프로세스나 쓰레드를 생성하여 처리했다. 하지만 프로세스를 생성하는 시간이 오래 걸리기 때문에 요청이 들어오기 전 프로세스를 미리 생성하는 PREFORK 방식을 사용한다. 만약 만들어 놓은 프로세스가 모두 할당되었다면 추가로 만든다.
이런 구조는 확장성이 좋아 개발하기 쉽다는 장점이 있다. 모듈이라는 개념으로 수많은 기능을 덧붙일 수 있다. 이 모듈을 통해 다른 프로그램과의 연동도 가능하다.
하지만 1999년대부터 사용자 수가 급격히 늘어나면서부터 문제가 생기기 시작했는데 서버에 동시에 연결된 커넥션이 많아졌을 때 더 이상 커넥션을 형성하지 못하는 C10K(Connection 10000 Problem) 현상이 일어나기 시작했다.
이 C10K 현상은 아파치 서버의 구조가 주 문제였다. 첫 번째로 커넥션이 형성될 때마다 프로세스가 할당되기 때문에 메모리가 부족하였고 두 번째로 위에서 말한 확장성이라는 장점이 오히려 단점이 되어 무거운 프로그램이 되었다. 그리고 세 번째로 많은 커넥션 요청이 들어오면 CPU는 계속해서 프로세스를 바꿔가며(Context Switching) 일해야 됐기 때문에 CPU에 부하가 계속해서 증가했다.
-> 즉, 아파치의 구조는 수많은 동시 커넥션을 처리하기에는 부적합했다고 할 수 있다.
Nginx 동작 방식
트래픽이 증가하면서 Apache의 한계를 극복하기 위해 Nginx가 등장하였다. Nginx는 *Event-Driven 구조로 동작하기 때문에 한 개의 프로세스만 생성하여 사용하고 비동기 방식으로 요청들을 동시적으로 처리할 수 있다.
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는 개발자가 직접 모듈을 만들기가 까다롭다는 단점이 있다.
하지만 단점을 커버하는 아래와 같은 장점들이 있다.
- 동시 커넥션 양 최소 10배 증가(일반적으로 100 ~ 1000배 증가)
- 동일한 커넥션 수일 때 속도 2배 향상
- 동적 설정 변경
- ex) 운영 도중에도 서버 추가 가능
Apache Multi Processing Module(Apache MPM)
이에따라 최근에 Apache도 MPM(Multi Processing Module)이라는 모듈을 추가해서 성능을 개선하게 되는데 MPM 이란 Apache 서버를 어떤 방식으로 운영할지 선택할 수 있게 해주는 모듈이다. 안정성이나 하위 호환이 필요하다면 기존의 PREFORK 방식, 성능 향상이 필요하다면 WORKER라는 스레드를 만들어 WORKER가 요청을 처리하는 방식으로 사용할 수 있다.
그러면 무조건 이제 Nginx를 써야되는거야?
앞에서 Nginx를 계속해서 칭찬하긴 했지만 아직까지 누군가가 압도적으로 점유하고 있는 게 아니고 Nginx와 Apache가 호각으로 1, 2등을 다투고 있다. 그 이유는 Apache도 Nginx보다 오래전부터 업데이트를 해왔기 때문에 그만큼 안전성, 확장성 측면에서는 Nginx보다 더 뛰어나다. 그렇기 때문에 상황에 맞게 유동적으로 선택하면 될 것이다.
애초에 이 두 웹서버는 탄생하게 된 이유부터 다르다. 아파치 때는 안정성과 확장성이 중요했고 Nginx 때는 트래픽이 빠르게 치고 올라오던 시절이라 동시 커넥션이 중요했기 때문이다.
Nginx와 Apache에 대해 알아봤으니 이제 Nginx가 제공해 주는 기능들에 대해 한번 알아보자
리버스 프록시(Reverse Proxy)
클라이언트 요청을 대신 받아 내부 서버로 전달해 주는 것을 리버스 프록시라고 하는데 서버 정보를 클라이언트로부터 숨겨줍니다.
예를 들어 아래처럼 구성하여 /로 요청 시 3000번 포트로 매핑해주고 /api로 요청하면 8080번 포트로 매핑해줄 수 있습니다.
로드밸런싱(Load Balancing)
하나의 서버에서 받는 요청을 여러 대의 서버가 분산 처리할 수 있도록 요청을 나누어 주어 성능, 확장성 및 신뢰성을 향상시킬 수 있다.
캐싱(Caching)
클라이언트가 요청한 내용을 캐싱 하여 같은 요청이 오면 캐시에 저장된 내용을 전송해 전송 시간을 절약할 수 있고 불필요한 외부 전송을 막을 수 있다.
참고: 우테코 테코톡(Nginx)
*틀린 부분이 있으면 언제든지 말씀해 주시면 공부해서 수정하겠습니다.