본문 바로가기
아키텍쳐

Nginx 는 어떻게 구성되어 있고, 어떻게 동작하는가?

by hayz 2022. 11. 13.


nginx 란? 간단히 말하자면 

고성능의 웹서버로 높은 트래픽을 처리하기 위해 만들어졌습니다. 기존에 apache 웹서버를 통해 사용했을때 생길 수 있는 한계를 해결하기 위해 비동기 방식으로 요청을 처리하고 매 요청 마다 프로세스와 스레드를 생성하지 않기 때문에 apache 웹서버보다 적은 자원으로 효율적으로 운영됩니다. 또한 보다 많은 수의 요청을 처리할 수 있습니다. 

 

 

Advanced Load Balancer, Web Server, & Reverse Proxy - NGINX

NGINX accelerates content and application delivery, improves security, and facilitates availability and scalability for the busiest websites on the Internet.

www.nginx.com


nginx 는 어떤 구조를 가지고 있을까?

앞서 말씀드린 것을 보면 nginx 는 다른 웹서버들 과 다른 구조를 가지고 있다는 것을 추측해 볼 수 있습니다. 과연 nginx 는 어떤 구조를 가졌길래 수많은 요청들을 동시에 처리할 수 있을까요? 

 

우선 아래의 관점을 토대로 nginx 의 구조를 살펴보도록 하겠습니다. 

  • 어떻게 nginx 는 프로세스를 만들고, 효율적으로 관리할까?
  • 동시에 요청을 처리하기위해 nginx 에서 사용한 non-blocking 과, event-driven 구조란 어떤걸까?

 

1.  nginx 의 프로세스 관리 방법

nginx 는 하나의 마스터 프로세스와 여러개의 워커 프로세스들로 구성되어 있습니다.  아래 그림으로 예시를 보면, nginx 마스터 프로세스가 1개 존재하고, 4개의 워커 프로세스가 떠있는 모습을 확인할 수 있습니다. 그리고, 캐시 프로세스를 둬서 디스크에 저장하는 대신 메모리에서 접근할 수 있도록 되어 있습니다. 

 

출처: https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/

위 그림에 나온 컴포넌트 들의 역할을 하나씩 보자면, 

  • 마스터 프로세스(master process): config 를 읽거나, 포트를 붙이거나, 자식 프로세스들을 생성하거나 하는 등의 관리자로써의 역할을 함
  • 캐시 로더(cache loader; CL): 캐시의 역할 대로, nginx 가 시작할 때, 디스크 기반의 데이터들을 메모리로 올리는 역할을 수행합니다.
  • 캐시 매니저(cache manager; CM):  캐시에 올라와 있는 데이터들을 주기적으로 정리해서, 캐시 자체의 크기가 커지지 않도록 조정합니다. 즉, 어떤 데이터를 남기고 어떤 데이터를 지울지 등을 결정하게 됩니다. 
  • 워커 프로세스(worker process): 네트워크 연결 관리, 디스크로 부터 데이터 읽고 쓰기, 서버와의 커뮤니케이션 등.. 모든 일을 하게 됩니다. 

 

워커 프로세스의 수는 nginx config 에서 설정할 수 있습니다. 물론, 자동으로 설정되도록 할 수도 있습니다. 

worker_processes auto;

각 워커 프로세스는 단일 스레드로 동작하고, 독립적으로 동작합니다. 그러면서, 새로운 연결을 잡고, 처리하는 과정을 반복하게 됩니다. 각 프로세스는 공유 리소스에 대해 공유 메모리를 사용하여 통신할 수 있습니다.

 

2.  nginx 의 워커 프로세스의 내부 동작 방법

출처: https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/

각 nginx 워커 프로세스는 nginx 설정 값에 맞춰서 초기화 되고, 마스터 프로세스로 부터 소켓에서 이벤트를 기다리며 할당 받을 소켓 정보들을 받습니다. 여기서 말하는 이벤트란.. 새로 요청되는 연결 (connection) 을 의미합니다. 이러한 이벤트 들은 state machine 들에 의해서 할당됩니다. (state machine 이란, 상태 머신 이라고도 하며 특정 상태와 조건에 따라 어떤 행동을 할지 결정되는 모습이라고 생각하면 됩니다.) nginx 에서는 HTTP state machine 과 더불어 stream state machine 과 mail state machine 까지 같이 사용하고 있습니다. 이 state machine 을 통과하면, nginx 가 이 요청을 어떻게 처리할지 판단되어 나오게 됩니다. 

 

state machine 은 하나의 규칙들이 정의된 형태라고 보시면 됩니다. 이러한 state machine 방식은 nginx 를 포함한 다른 웹서버에서도 쓰이는 방법입니다. 하지만, 가장 큰 차이는 "blocking" 이냐 "non-blocking" 이냐의 차이가 있습니다. 

 

만약 blocking 이라면 어떻게 동작할까요?

여러 연결들이 들어올 때, blocking 방식이라면, 각 프로세스들은 항상 하나의 연결이 끝날때까지 그 연결을 잡고 있는 형태로 있으며, 사용자가 다음 동작을 진행할때까지 대기하는 상태로 자원과 시간을 낭비하게 됩니다. 즉, 모든 각 활성화된 HTTP 연결들은 프로세스 혹은 스레드를 필요로 한다는 것입니다. 만약에 작은 비용을 요구하는 연결이었을 경우, 보다 큰 자원을 잡고 있기 때문에 낭비가 심한 형태를 띄우게 됩니다. 이처럼 요청에 대해 프로세스를 할당하는 방식이 process-driven 이라고 볼 수 있습니다. 

 

하지만 nginx 에서 사용하는 non-blocking 은 어떻게 동작할까요?

listen 중인 소켓에 이벤트가 들어오면, 새로운 요청이 들어온 것입니다. 이때 워커 프로세스는 새로운 요청을 맺도록 소켓을 생성하게 됩니다. 그리고 해당 소켓에 이벤트가 들어온다면 새로운 요청을 보내게 된거고 해당 요청을 즉시 수행시켜 줍니다. 

하지만 위 과정에서 중요하게 봐야할 것은 프로세스가 절대 대기 상태로 존재하지 않는다는 것입니다. 요청이 중단 되고 대기 상태로 머무르게 되면 즉시 다른 요청으로 넘어가서 다른 응답을 주게 됩니다. 이러한 방식은 이벤트가 들어올 때마다 요청이 처리 되기 때문에 event-driven 이라고 볼 수 있습니다. 

 

예를 들어, 요리를 할 때 라면 만들고, 김밥 만들고, 떡볶이 만들고 순서대로 진행하는 것이 아니라, 라면에 스프 넣고 물이 끓는 동안 김밥을 말고, 떡볶이 물이 끓으면 떡과 고추장을 넣어주고 다시 라면으로 돌아가서 면을 넣어주고 하는 방식으로 동시에 여러 작업들을 진행하며 불과 시간을 효율 적으로 쓸 수 있게 되는 것입니다. 

 


 

위 내용을 통해 어떻게 해서 nginx 가 요청을 빠르게 많이 처리할 수 있는지 간단하게 살펴보았습니다. 

이후에는 이러한 nginx 의 활용 방법 들에 대해서 알아보도록 하겠습니다. 

 

 

 

참고

https://www.nginx.com/resources/library/infographic-inside-nginx/

 

Inside NGINX Infographic | NGINX

Check out this infographic to see why NGINX is the best choice for your apps and users.

www.nginx.com

https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/

 

Inside NGINX: Designed for Performance & Scalability

Take a deep dive inside NGINX and learn why NGINX is perfectly suited for applications and servers that require high performance and scalability

www.nginx.com

 

댓글