20.3 Apache HTTPD 튜닝
Apache Httpd MPM모듈
아파치 웹 서버는 다양한 환경과 플랫폼에서 동작할 수 있도록 강력하고 유연하게 설계되었다. 아파치는 모듈화된 설계로 다양한 환경에 적응해 왔고, 관리자는 환경에 적합하게 컴파일이나 실행 시 어떤 모듈을 로딩할지 선택하여 서버가 제공하는 기능을 결정할 수 있다.
Apache Httpd 2.0은 이러한 모듈화된 설계를 웹 서버의 가장 기본적인 부분까지 확장하였다. HTTPD서버는 자식 프로세스에 분배하는 다중처리 모듈(Multi-Processing Modules, MPM)을 통해 시스템의 네트워크 포트에 연결하고, 요청을 받아들이며, 받아들인 요청을 처리하는 방법을 선택할 수 있다.
MPM은 Apache Httpd 2.0 서버에서 요청을 처리하는 부분이다. Apache 웹 서버의 MPM은 4가지 종류가 있다.
- prefork
- worker
- perchild
- winnt
다음은 리눅스 환경에서 Apache HTTPD의 MPM 을 확인하는 방법이다.
# httpd -l
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c
Prefork MPM 과 Worker MPM 의 비교
Apache HTTPD 2.0 버전에 추가된 MPM 중 가장 많이 사용하는 Prefork MPM과 worker MPM의 차이점을 간단하게 설명한다. 먼저 prefork MPM은 Apache 1.3 버전에서 사용하던 방식으로 자식 프로세스를 먼저 시작해 놓고, 클라이언트 요청에 대해서 각각의 자식 프로세스가 통신을 담당하는 방식이다. 따라서 자식 프로세스가 어떤 원인으로 정지하더라도 다른 자식 프로세스에 영향을 주지 않는 특징이 있다. Worker MPM은 자식 프로세스에서 멀티 스레드로 실행되며, 클라이언트 요청을 스레드가 처리하는 방식이다. 하나의 프로세스가 멀티 스레드를 이용해 여러 요청을 담당하게 되어 prefork방식과 비교할때, 시작 시 프로세스 수를 줄일 수 있고, 메모리 사용량이 낮으며, 부팅 시간이 빠르다.
(r : 요청수, n : 자식 프로세스 수, m: 각 자식 프로세스당 스레드 수)
| Prefork MPM | Worker MPM |
|---|---|
| 프로세스(멀티 프로세스)를 사용해 요청을 처리 | 멀티 스레드와 멀티 프로세스를 사용해 요청을 처리 |
| r = n | r = n × m |
| PHP를 사용하는 웹사이트에서 높은 성능이 필요하다면 prefork MPM 을 사용 | 스레드는 메모리를 작게 사용하고 프로세스 방식보다 시작 시간이 빠르며 성능이 좋다. |
![]() | ![]() |
<IfModule prefork.c>
StartServers 8
MaxClients 256
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxRequestsPerChild 4000
</IfModule>
| | |
<IfModule worker.c>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
표 1. Apache HTTPD의 prefork방식과 worker 방식의 비교
위의 예에서 보면 StartServers는 prefork와 worker 모두 있는 항목이지만 prefork는 8개이고 worker는 2개이다. 이 차이는 프로세스와 스레드의 차이에 의한 것이다. 위의 설정에서 prefork 는 5에서 20개의 프로세스를 항상 유지한다. worker는 25에서 75개의 여유 스레드를 유지한다. 반면 worker 는 프로세스의 제한은 명확하게 설정되어 있지 않다. 위의 예에서 worker는 시작 시 2개 프로세스에서 사용 가능한 스레드가 범위에 없는 경우 프로세스를 추가하거나 불필요한 프로세스를 제거한다. 또한, MaxRequestsPerChild 0으로 무제한으로 설정되어 있다. 서버는 요청을 기다리고 있는 서버 스레드 개수를 체크하여 MaxSpareThreads, 즉 75개 이상이 있으면 서버 프로세스를 제거하고, MinSpareThreads 25개 미만인 경우 새로운 프로세스를 생성한다.
Apache HTTPD MPM 주요 설정
다음 표에서 Prefork 와 Worker 에서 사용하는 속성들을 정리한다.
| 속성 | 설명 | 비고 |
|---|---|---|
| StartServers | Apache HTTPD 시작 시에 생성하는 프로세스 수를 지정한다. 여기서 지정한 프로세스 수는 시작 시에만 의미가 있으며, prefork의 경우 시작 이후 프로세스 수는 MinSpareServers와 MaxSpareServers 지정 값에 따라 조정된다. | |
| MinSpareServers | 클라이언트 요청을 기다리는 httpd서버 프로세스(idle 상태)의 최소값을 지정한다. 여기에서 지정한 값보다 프로세스 수가 작아지면, 새로운 프로세스를 생성한다. 트래픽이 많지 않은 사이트의 경우 초기값으로 설정할 것을 권장한다. | prefork만 해당 |
| MaxSpareServers | 클라이언트 요청을 기다리는 httpd서버 프로세스(idle 상태)의 최대값을 지정한다. 여기에서 지정한 값보다 프로세스 수가 많아지면 프로세스를 제거한다. 트래픽이 많지 않은 사이트의 경우 초기 값으로 설정할 것을 권장한다. | prefork만 해당 |
| ServerLimit | prefork의 경우 서버 프로세스와 클라이언트 수가 같아지기 때문에 MaxClients에 설정한 최대값이다. worker의 경우 ThreadLimit와 함께 계산하여 MaxClients에 설정한 최대값이다. | prefork만 해당 |
| MaxClients | 동시에 처리할 수 있는 httpd서버 프로세스의 수를 지정한다. 즉, 클라이언트의 최대 접속 수이다. prefork의 경우는 프로세스 수를 지정하고 worker의 경우는 스레드 수를 지정한다. | |
| MaxRequestsPerChild | 하나의 httpd 프로세스로 처리할 수 있는 요청의 최대값을 지정한다. 0은 무제한이다. | |
| MinSpareThreads | 클라이언트 요청을 기다리는 스레드(idle 상태)의 최솟값을 지정한다. prefork의 MinSpareServers에 해당한다. | Worker만 해당 |
| MaxSpareThreads | 클라이언트 요청을 대기하는 스레드(idle 상태)의 최대값을 지정한다. prefork의 MaxSpareServers에 해당한다. | Worker만 해당 |
| ThreadsPerChild | worker 프로세스 내에서 생성하는 스레드 수를 지정한다. | Worker만 해당 |
표 2. Apache HTTPD MPM 주요 속성
Worker MPM 으로 전환
Apache HTTPD 를 사용할 때 prefork MPM 방식을 적용해서 성능의 문제가 된다면 worker 방식으로 변경한다.
Prefork 경우 ServerLimit는 Apache프로세스의 MaxClients에 설정 가능한 최대값을 설정한다. 이는 ‘동시 클라이언트 수(MaxClients) = 최대 서버 프로세스 수(ServerLimit)’가 되며, ServerLimit는 MaxClients 값 이상으로 설정할 필요가 없다.
Worker 경우에는 ‘MaxClients(총 스레드 수) / ThreadsPerChild(하나의 프로세스가 생성하는 스레드 수) = 최대 서버 프로세스 수(ServerLimit)’가 된다.

앞서 설명한 내용들에 대한 이해를 돕기 위해 다음 예를 들어 설명한다.
<IfModule worker.c>
ServerLimit 60
StartServers 2
MaxClients 1500
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 1000
</IfModule>
예제에서는 MaxClients(접속 가능한 요청의 최대값)를 1500으로 할 때, ServerLimit 설정 값은 ‘1500(MaxClients)/25(ThreadsPerChild)=60프로세스(ServerLimit)’가 되므로 60이 된다.


