인생을 코딩하다.

[Network] Apache MPM vs Nginx 본문

Network

[Network] Apache MPM vs Nginx

Hyung1 2021. 2. 17. 04:05
728x90
반응형

Apache와 Nginx는 현재까지 가장 폭넓게 쓰이는 2가지의 오픈소스 웹 서버이다.

Apache

Apache는 Client 요청을 받으면 MPM(Multi Processing Module : 다중처리모듈)이라는 방식으로 요청을 처리하며 대표적으로 Prefork와 Work방식이 있다.

MPM

서버는 시스템의 네트워크 포트에 연결하고, 요청을 받아들이며, 받아들인 요청을 처리하기 위해 자식들에게 분배하는 다중처리 모둘(Multi-Processing Modules, MPMs)을 선택할 수 있다. 클라이언트에서 요청을 받으면 MPM 방식으로 처리를 하는데 대표적으로 PreforkWorker방식이 있다.

  • 커넥션 생성(binding, acecept)
  • 커넥션 분배 프로세스든 스레드든 해당 커넥션에 대한 요청을 담당 -> 프로세스든 스레드든 해당 커넥션에 대한 요청을 담당

MPM 모듈 종류(UNIX 계열)

 

Prefork MPM -> 프로세스가 요청들을 담당해준다.

  • 위 프로세스가 시작되고, 하위 프로세스가 생성된다. 서버는 들어오는 요청을 처리하기 위해 몇 개의 생성된 자식을 계속 실행한다.
  • 요청량이 많아질수록 프로세스를 복제하여 동작한다.
  • 각 프로세스는 한 번에 한 연결만 처리하고 요청량이 많아 질수록 프로세스는 증가하지만 복제시 메모리영영까지 복제되어 동작하므로 프로세스간 메모리 공유가 없어 안정적이라 볼 수 있다.
  • 즉, 단일 스레드 로직에서 작동하며 각 서버 프로세스는 한 번의 하나의 웹 요청을 처리한다.
  • 하지만 프로세스를 복제하는 방식이기 때문에 메모리가 많이 소비된다. connection 수 = 프로세스 수 라고 보면 됨

Worker MPM -> 스레드가 요청을 담당해준다.

  • Prefork는 한 개의 프로세스가 한개의 스레드로 처리가 되는 동작방식이다. 그에 비해 Worker 방식은 한 개의 프로세스가 여러 쓰레드를 사용하여 요청을 처리한다.
  • 쓰레드를 사용하기 때문에 쓰레드간의 메모리를 공유하며 Prefork 방식보다 메모리 소모가 적다.
  • 즉, 동시에 여러 스레드를 지원하고 이것은 Apache가 좀 더 효율적이고 확장가능하도록 돕는다.
  • 통신량이 많을때 유리하다.

 

그런데 이렇게 쓰레드나 프로세스를 여러개 만들게 되면 단점이 있다. 만약 10000개의 연결이 동시에 처리가 된다면?

  • 메모리...프로세스당 1MB가 필요하다면.. -> 10000 * MB == 10GB!
  • 컨텍스트 스위칭 (누구를 실행해야 하지?) -> 4코어면.. 잘 분배되도 2500개?, 컨텍스트 스위칭 오버헤드 * 2500

O(n) // n은 요청수에 비례, 요청이 커지면 문제가 생길 수 있다.

동시에 처리되야 할 숫자에 영향을 받지 않으려면? O(n) -> O(1)이되면 된다.

 

이 단점을 Nginx가 보완해준다..허나 단점도 존재한다.

Nginx

Nginx 는 Event-Driven 방식으로 동작한다. 한 개 또는 고정된 프로세스만 생성 하고, 그 프로세스 내부에서 비동기 방식으로 효율적으로 작업을 처리한다. 따라서 동시 접속 요청이 많아도 Process 또는 Thread 생성 비용이 존재하지 않는다. 

  • 웹서버라는 역할에 최적화
  • 비동기 방식에 적합한 입력들 (CPU 점유를 적게하는)
  • Module로 구성
  • Non-blocking
  • Single-threaded(worker 프로세스)

 

* Event-Driven 방식은 작업을 하다 I/O, socket read/write 등 CPU가 관여하지 않는 작업이 시작되면 기다리지 않고 바로 다른 작업을 수행한다. 그러다 진행중인 I/O 등의 작업들이 끝나면 이벤트가 발생하여 그 다음 작업을 처리하게 된다.

 

중점적으로 봐야 할 부분은 새로운 요청이 들어오면 NGINX의 Worker 프로세스 내부 listener가 요청을 받아 전달한다는 점이다. 각 Worker 프로세스는 내부에서 효율적으로 처리한다. Worker 프로세스는 HTTP 요청과 응답을 처리하는 동안 계속해서 listener를 통해 요청을 받고, 읽고, 쓰기를 반복한다. 각 커넥션마다 프로세스와 쓰레드는 복제(fork)하지 않는다. 따라서 부하가 증가하더라도 CPU/메모리 사용량이 크게 증가하지 않는다.

 

좀더 간단한 그림으로 동작과정을 말하자면,

1. Reactor는 event가 들어오면 알맞는 handler로 dispatch를 해준다.

2. Handler는 이 dispatch된 event를 받아서 처리하는 역할을 수행

 

* Reactor : Reacator는 별도의 스레드에서 실행되며 발생한 I/O 이벤트는 dispatching되어 해당 이벤트 처리기로 보내 처리한다.

* Handlers : Reactor로부터 I/O 이벤트를 받아 실제 작업을 수행한다.

 

Event-Driven 방식은 Reactor pattern을 사용한다고 한다. 간단하게 요약해보자면,

 

Reactor 패턴은 하나 이상의 클라이언트로 부터의 요청(입력)을 동시처리하기 위해서 사용하는 패턴이다. 서버는 각 입력에 대해서 받을 이벤트를 동적으로 등록/해제하는 식으로 처리해야할 입력과 이벤트를 관리할 수 있다.

 

  1. 새로운 연결이 들어온다.
  2. 이 연결과 연결에 대해서 처리할 이벤트를 일괄 등록한다.
    • 이벤트는 "입력 데이터", "출력 데이터", "종료"등이 있을 수 있다.
  3. 주기적으로 이벤트를 확인한다.
  4. 이벤트가 발생하면 dispatcher 에 전달해서 처리한다.
  • 2번이 multiplexing과정이다. 즉 여러 개의 입력을 처리할 수 있도록 다중화 한다. 3번 과정이 demultiplexing 과정으로 이벤트가 발생한 "하나의" 입력을 찾아낸다.
  • 마지막으로 dispacher이 데이터를 처리한다.기본적으로 demultiplexing 에서 multiplexing의 과정이 단일 스레드에서의 처리에 적합한 관게로 단일 프로세스 프로그램에서 두 개 이상의 입력을 처리하기 위해서 주로 사용한다.

Nginx를 사용하기 좋은 예는

로드밸런싱

  • 효율성
  • 안정성 ( 누군가 죽어도 다른애가 있다.)

리버스 프록시

  • 보안
  • 유연성 ( 외부에서 직접적으로 모르기에)

레이턴시 감소 ( 앞단에 웹서버 역할을 해주는 애가 대신해주면 자신이 할 일에 집중할 수 있다.)

  • 압축
  • SSL(암호화)
  • 캐시

정리 : 

Apache 

  • 클라이언트 요청을 처리하기 위해 멀티스레드 방식을 따름
  • 웹 서버 자체 내에서 동적 컨텐츠를 처리
  • 모듈을 동적으로 및 언로드 ( 더 유연하게 만들기)

그러나 웹 트래픽이 많아지면 여러 요청을 동시에 처리 할 수 없다. 클라이언트 요청을 처라하기 위한 다중 스레드 접근 방식을 따르고 스레드는 한 번에 하나의 연결만 처리 할 수 있기 때문.

 

Nginx

  • 이벤트 중심 접근 방식을 사용하여 클라이언트 요청 제공
  • 제한된 하드웨어 리소스로도 여러 클라이언트 요청을 동시에 효울적으로 처리
  • 단일 스레드를 통해 여러 연결을 처리할 수 있음
  • 최소한의 리소스로 웹 서버의 아키텍처를 개선하기 위해 독립형 HTTP 서버로 배치 가능

하지만 동적 컨텐츠를 기본으로 처리 할 수 없다. 동적 컨턴체에 대한 기타 요청을 처리하려면 이를 실행하기 위해 외부 프로세서로 전달하고 렌더링 된 콘첸츠가 다시 전송 될 때까지 기다려야한다. 즉, 프로세스 속도 저하

 

출처 : 

old.zope.org/Members/ike/Apache2/osx/configure_html

www.joinc.co.kr/w/Site/SoftWare_engineering/pattern/reactor

blog.cornsworld.co.kr/429

taetaetae.github.io/2018/06/27/apache-vs-nginx/

webinstory.tistory.com/entry/Apache-vs-Nginx-%EB%B9%84%EA%B5%90

blog.naver.com/PostView.nhn?blogId=tmondev&logNo=220737182315

youngmind.tistory.com/entry/Apache-vs-Nginx

728x90
반응형
Comments