APACHE vs. NGINX 성능 비교



들어가며
스마트폰이 보편화된 현대의 사회적인 변화로 PC뿐 아니라 모바일/태블릿을 통해 웹 페이지를 접근하는 빈도가 계속적으로 증가하게 되었으며 그에 맞게 웹 서버 역시 늘어난 동시 접속 수를 얼마나 잘 수용할 수 있는가가 중요한 관건이 되었다.
 
지난 1부에서는 웹 서버 트래픽 폭주에 대비하여 아파치 + 톰캣 서버의 적절한 설정값을 찾는 과정을 살펴보았다. 이번 글에서는 경량화 웹 서버로 불리며 웹 서버 점유율을 높이고 있는 NGINX가 무엇인지, 주목받는 이유와 아파치와의 차이점은 무엇인지 알아보도록 하겠다. 지난 1부를 보고 싶다면 아래 링크를 통해 확인할 수 있다.






APACHE의 하락세, NGINX의 상승세
아래 그림은 영국 보안업체 NetCraft에서 약 104백여개 사이트를 대상으로 2016 3월 조사된 최근 웹 서버의 회사별 점유율 현황이다.


 
웹 서버 점유율. 2016.03 기준 (출처)


전체 사이트를 기준으로 보면 2000년대에 독보적인 점유율을 보이던 아파치가 마이크로소프트 IIS(Internet Information Server)와 비슷한 점유율을 보이고 있고, 그 뒤를 NGINX가 따르고 있다. 하지만 실제 Active Site를 기준으로 보면 아직도 아파치가 절반 가량의 점유율을 보이고 있고, NGINX 16%, 마이크로소프트가 10%를 점유하고 있다.
 
중요하게 볼 부분은 웹 서버의 Market Share는 계속적으로 변하고 있으며, 추이를 봤을 때 아파치는 점유율 감소, NGINX는 증가 추세를 보이고 있다는 것이다. NGINX는 가벼움과 높은 성능을 목표로 2004년 첫 등장 이후 현재까지 신규서비스를 중심으로 점유율에 가속을 붙이고 있다. 현재 티몬에서도 아파치 웹 서버에서 NGINX로 변경이 진행되고 있다.
 
그렇다면 왜? 어떤 이유로 NGINX를 쓰는 추세일까?
 
 

NGINX
아래는 전체적인 NGINX 아키텍쳐 구조다.


 

NGINX의 아키텍쳐(Event Driven 방식) 


[NGINX의 특징]
-      Module로 구성
-      Event-driven 이면서 비동기 방식(Asynchronous)으로 동작
-      Single-threaded(worker 프로세스)
-      Non-blocking
 

중점적으로 봐야 할 부분은 새로운 요청이 들어오면 NGINX의 Worker 프로세스 내부 listener가 요청을 받아 전달한다는 점이다. Worker 프로세스는 내부에서 효율적으로 처리한다. Worker 프로세스는 HTTP 요청과 응답을 처리하는 동안 계속해서 listener를 통해 요청을 받고, 읽고, 쓰기를 반복한다. 각 커넥션마다 프로세스와 쓰레드는 복제(fork)하지 않는다. 따라서 부하가 증가하더라도 CPU/메모리 사용량이 크게 증가하지 않는다.
 
반면 아파치의 Prefork MPM방식은 기본적으로 요청 하나당 프로세스와 쓰레드 기반으로 동작한다. 때문에 접속당 CPU와 메모리 사용이 증가하여 성능 저하를 일으킬 수 있다. 이를 극복하기 위해 2.4.X 버전부터 event MPM 방식이 기본 모듈로 추가되고 확장성과 성능향상을 위한 proxy 모듈이 추가되었지만, 자원 사용 측면에서 NGINX의 순수 Event driven 서버들과 비슷하다고 보기엔 어려움이 있다.
(NGINX Event Driven방식에 대한 자세한 사항: 링크 참조)


 
아파치의 Prefork MPM 방식


 

NGINX vs. APACHE
이제 본격적으로 1부에서 테스트한 아파치의 Prefork MPM 방식과 NGINX(Event Driven 방식)를 비교해 보겠다. 아파치와 NGINX는 기본 방식 자체가 다르므로 동일한 환경으로 맞추는 것은 어려움이 있어, 각 설정의 임계치에 근접하는 부하를 주고 테스트 하였다.
 
1. NGINX

1-1) Server : 


























1


2


3


4


5


6


7




# nginx.conf


worker_processes  1;


...


events {


    worker_connections  1024;


    ...


}

































- worker_processes는 작업 프로세스의 개수를 의미하며, CPU 코어 개수만큼 할당하도록 권장하고 있다. (Default : 1) 
특정 버전 이상에서부터 숫자가 아닌 "auto"로 설정이 가능하며, 자동으로 찾아서 세팅된다. (auto 설정을 하고 테스트해보니 서버의 CPU 코어 수만큼 할당되는 것을 알 수 있었다.)

- worker_connections는 하나의 프로세스가 동시에 처리할 수 있는 커넥션 수를 의미한다. (Default :512)
동시 수용 가능한 최대 접속 수 = worker_processes * worker_connections 이므로 위 예시에서 서버가 동시에 수용 가능한 최대 접속 수는 1024이다.
 
 

1-2) Client(Jmeter) : 동접은10부터 1000까지 순차적으로 초당 10씩 증가시키며 최대치인1000에 도달하였을 때 30초간 유지



 


1-3) NGINX 테스트 결과

<Summary Report>


 
<Transaction Per Seconds(TPS)>

 


마지막까지 평균 2614/sec TPS를 유지한다.
* 마지막에 떨어지는 부분은 요청이 없어지는 시점이다.

 
 
<Response Code / Per Second>

0.04% 정도의 HTTP Status 200외의 Error가 발생하였다.
 

 
2. 아파치
NGINX와 아파치 간의 순수한 비교를 위해 변수 통제로 백단의 WAS(톰캣)에서의 병목이 발생하지 않도록 ServerLimit / MaxClient 값을 톰캣 MaxThread값으로 설정해둔 256의 절반 이하 수준으로 설정하였다. 테스트 페이지는 static한 이미지만 있는 jsp 페이지로 테스트하였다.
 
2-1) Server : ServerLimit=100 / maxClient=100

2-2) Client(Jmeter) : 동접은10부터 100까지 순차적으로 초당 10씩 증가시키며 최대치인100에 도달하였을 때 30초간 유지  


 



 
2-3) 아파치 테스트 결과 

<Summary Report> 


 
<Transaction Per Seconds(TPS)>


 
평균적으로 1716.7/sec이며, 마지막 10초간은 에러발생으로 TPS가 급격히 감소하였다.
 
 
 
<Response Code / Per Second>


최대 동접을 30초간 유지하게 될 때 마지막 10초간은 부하를 버티지 못하여 에러가 발생하였고, 에러 발생으로 인해 위의 차트와 같이 TPS는 급격히 감소하였다.
 
앞서 언급한 내용과 같이 기준이나 조건이 다른 부분이 있어 단순하게 두 가지의 TPS만 놓고 수치상의 성능 비교는 다소 어려움이 있다. 이번 테스트 결과에서는 수치상의 비교가 아닌 아파치 / NGINX 각각의 차트 추이를 비교하여 그 차이점을 중점적으로 보면 좋을 것 같다.
 
 
 

3. 결과 그래프 비



NGINX의 경우는 최초 동접이 적은 시점부터 TPS가 올라가다가 적정 수준을 끝까지 유지하는 반면, 아파치의 경우는 커넥션이 임계치에 도달하여 유지되는 시점에 트래픽을 커버하지 못하고 에러가 발생하면서 TPS가 급격이 떨어지는 결과를 보였다. 이러한 측면에서 볼 때, 일반적인 상황에서 NGINX가 아파치(Prefork MPM)보다 조금 더 많은 커넥션을 처리한다고 예상해 볼 수 있다.
 
이번 테스트 결과는 약식으로 진행해본 테스트이고 일부에 해당하는 내용이므로 절대적으로 NGINX가 아파치 보다 성능 면에서 우위에 있다고 보기는 어렵다는 점을 참고하기 바라며, 직접 설정을 바꾸면서 테스트 해보는 것도 좋을 것 같다.
 
미처 테스트하지 못한 부분(아파치 웹 서버의 다른 방식이나 기타 웹 서버들과의 비교)을 보완하기 위해, 주요 웹 서버 성능 Benchmark를 비교한 사이트를 아래 링크 첨부 하였으니 참고하면 이해에 많은 도움이 될 것으로 생각한다.

 


마치며
NGINX를 실무에서 사용해 본 경험이 이번이 처음이라 거의 전무하지만, 기존 아파치 웹 서버와 비교하여 NGINX를 살펴보고 간단한 환경을 구성하여 테스트 해본 내용을 글에 포함시켰다. 테스트 과정에서 예상했던 것과 다른 방향의 결과가 나오거나, 비교하기 애매한 부분들이 있어 다소 어려움이 있었다. 앞으로 NGINX를 실무에서 사용하면서 조금 더 관심을 갖고 부족한 부분들은 짚고 넘어가는 과정이 필요하다고 생각한다.
 
성능 최적화 관련된 책 또는 글을 보면 아주 당연한 이야기지만 공통적으로 나오는 말은 "절대적인 최적화 설정 값은 없다"는 내용이었다. 그만큼 서비스의 대상이나 특성, 서버의 물리적인 상태 등 고려해야 할 요소들이 다양하기에 정답이 없고, 여건이 된다면 성능테스트를 통해 최적화된 설정 값을 찾는 방법이 가장 좋다고 생각한다.
 
티몬에서는 서비스를 개발하는 부서와 웹 서버 / WAS 등 시스템을 담당하는 부서가 나뉘어 있어서, 관심이 없다면 웹 서버 / WAS설정은 신경 쓰지 않고 단지 로직 개발만 치중하게 될 수 있다. (다른 회사도 비슷하거나 크게 차이가 없을 것으로 생각한다) 버그없는 로직 개발도 물론 중요하지만, 이 글에서 소개한 정도만이라도 아파치 웹 서버 / 톰캣 / NGINX의 프로세스와 쓰레드 관련 설정 값에 대해 알고 있다면 조금이나마 도움이 될 수 있지 않을까 생각한다.
 
 
[참고]
엔진엑스로 운용하는 효율적인 웹사이트 (에이콘)

댓글 쓰기

0 댓글