본문으로 바로가기

apahce 최적화 튜닝

category 서버 & 시스템/Linux 2018. 8. 30. 14:42
반응형

<아파치 튜닝>


* 아래의 메뉴얼이 절대적이지 않음, 시템을 꾸준히 모니터링하면서 알맞은 값을 직접 찾아야함.

웹 서버를 며칠간 재시작하지 않고 놔둬서 현재 서비스 상태를 파악하는 게 가장 좋음


* apache 공식사이트에서 각버전의 Miscellaneous Documentation 메뉴로 확인

https://httpd.apache.org/docs/trunk/ko/misc/perf-tuning.html


1. 메모리를 이용한 부하 확인

 # netstat -nta | grep :80.*ESTABLISHED | wc -l \\ 아파치 서버와 클라이언트 사이의 동시 소켓 연결 개수(동시접속자 수 )를 확인 / maxclients 수 넘지 않도록 해야함



아파치벤치마킹 도구(ab) 이용하여 웹서버 부하 실행하여 시스템 상황 체크

[터미널 1]

# ab -n 3000 -c 200 http://[도메인]/ \\ 200명의 사용자가, 15번씩 총 3000번 요청, 사이트 주소 끝에 / 들어가있어야함


[터미널 2]

# free -m \\ 물리 메모리 확인

# ps aux | grep mysql | awk '{print $6}' | awk '{total = total + $1} END {print total/1024}' \\ mysql 메모리 사용량 측정

# ps aux | grep apache2 | awk '{print $6}' | awk '{total = total + $1} END {print total/1024}' \\ apache 메모리 사용량 측정

# ps aux | grep apache2 | wc -l \\ 아파치 프로세스 갯수 


아파치 프로세스 평균 메모리 사용량 = apache 메모리 사용량 / 아파치 프로세스 갯수

(전체메모리 - mysql 사용량) / 아파치 프로세스 평균 메모리 사용량 = 메모리 사용량이 전체 메모리에 다다르면 안됨




2. mpm 확인

동시접속 처리방법에는 프로세스를 이용하는 법(prefork 방식)과 스레드를 이용하는 법(worker 방식)이 있음. 아파치 서버의 기본 동작은 prefork 방식.


              Apache MPM Prefork                                  Apache MPM Worker

prefork MPM

worker MPM


프로세스(멀티프로세스)를 사용해 요청을 처리


자식 프로세스를 먼저 시작하고 클라이언트의 요청에 대해 

각각 자식의 프로세스가 통신을 담당


하나의 연결은 스레드가 하나인 자식 프로세스가 처리


자식프로세스가 어떤 원인으로 정지하더라도 

다른 자식 프로세스에 영향을 주지 않음


프로세스를 만드는 비용은 

스레드를 만드는 비용보다 더 크고 메모리를 더 많이 차지


하지만 프로세스간 메모리를 공유하지 않아 서로 독립적이기 때문에 

문제가 있는 연결이 다른 연결을 간섭하지 않음


안정성

멀티스레드와 멀티프로세스를 사용해 요청을 처리


자식 프로세스 안에 여러 스레드가 있고 이 스레드는 하나의 연결을 처리


 스레드를 만드는 것이 프로세스를 만드는 것보다 

속도가 더 빠르고 메모리를 덜 차지하지만, 

문제가 생긴 스레드는 자식 프로세스 안의 다른 스레드까지 망가뜨릴 위험이 있음


경쟁상태(race condition) 조심


성능



캐싱을 적극적으로 활용하면 아파치 프로세스가 10MB 정도 차지하지만 캐싱하지 않으면 프로세스당 메모리가 30MB까지도 잡힐 수 있음. 

즉, PHP 코딩이 아파치 프로세스의 메모리 사용량에 영향을 주고 최대동시접속연결수도 영향을 줌. 

MaxClients 값을 비롯해 StartServers 등의 값을 너무 크게 잡으면 오히려 아파치 프로세스의 점유 메모리가 더 커지는 현상이 있으므로 적당한 값을 지정.


# vi httpd-mpm.conf


<IfModule mpm_prefork_module>

StartServers 5 \\ apache데몬을 처음시작할 때 프로세스 갯수, minsparesrver나 maxspareserver와 동일한 값으로 설정

MinSpareServers 5 

MaxSpareServers 10

ServerLimit 180 \\ 최대 자식 프로세스의 수, maxclinet 수보다 작아야함

MaxClients 180 \\ 2000을 넘길 필요가 없다면 serverlimit와 동일한 값으로 지정

</IfMoudle>


MinSpareServers와 MaxSpareServers

요청을 기다리는 몇 개의 자식 프로세스를 여분으로 둘 지 범위를 지정. 

아파치 데몬이 프로세스의 개수를 이 범위 안으로 두기 위해 노력하지만 이를 보장하지는 않음. 

초당 4개 이상의 자식 프로세스를 생성(spawn)하지 않도록 설정. 

보통은 MinSpareServers 값은 MaxClients의 10~25% 정도 크기의 값으로 MaxSpareServers 값은 25~50% 크기의 값으로 지정. 

그러나 이 값이 커지면 아파치 프로세스의 점유 메모리도 함께 커지는 현상이 있으니 크다고 능사는 아니므로 유념.


아파치 웹 서버는 오픈소스로서 끊임 없이 패치하고 있지만 C로 작성되어 있어 메모리 누수(leak)나 무한루프 등의 서버 부하(load) 발생할 수도 있음. 

그래서 일정 횟수 동안 클라이언트 요청을 처리하고 프로세스가 죽도록 되어 있다.

아파치 매뉴얼에서는 디폴트로 클라이언트 요청을 10,000번 처리하고 죽는다고 함. 

이 클라이언트 요청을 몇 번 처리하고 프로세스가 죽을지는 MaxRequestPerChild 값의 변경해 지정할 수 있으며, 시스템 사양이 좋다면 이 값을 넉넉히 할 수 있으며 프로세스가 절대 죽지 않도록 하려면 0으로 합니다. 3000에서 4000 정도 주면 적당.




3. httpd.conf 설정

# vi httpd.conf


Timeout 10 \\ 소켓연결 유지시간

KeepAlive On

KeepAliveTimeout 2

MaxKeepAliveRequests 100 \\ KeepAlive 상태에서 처리할 최대 요청 수


Timeout 

클라이언트가 요청하여 아파치와 연결된 이후로 이 시간 동안 아무런 메시지가 없으면 오류로 처리. 네트워크 회선 상태가 좋지 않으면 이 값을 크게 할 수 있음. 

국내 사용자만 고려한다면 10초 정도 국외 사용자까지 고려하면 20초


KeepAlive

HTTP 프로토콜의 특성상 한 번 통신이 이루어지면 접속을 끊어 버리지만, KeepAlive On 상태에서는 KeepAliveTimeOut 시간 동안 접속을 끊지않고 다음 접속을 기다림.

즉, 한 번 연결된 클라이언트와 통신을 유지하고 있기 때문에, 다음 통신 시에 Connection을 생성하고 끊는 작업이 필요 없게 된다.


정적 자원( html파일, 이미지 파일 등 )으로만 구성된 웹 서버에 KeepAlive On으로 설정할 경우 약 50%의 성능 향상을 보인다고 한다.

단 이와 같은 성능 향상을 보이려면 서버가 바쁘지 않아야 하는데, 바쁜 서버 환경에서 KeepAlive On으로 설정해 놓을 경우,

모든 요청 마다 연결을 유지해야 하기 때문에 프로세스 수가 기하급수적으로 늘어나 MaxClient값을 초과하게 된다.

따라서 메모리를 많이 사용하게 되며 이는 곧 성능 저하의 원인이 됨. ( 대량 접속 시 효율이 떨어짐 )


KeepAliveTimeout

국외 접속자가 많으면 10초까지 지정할 수 있음. 10초 이상은 메모리 점유로 동시접속자가 크게 감소할 수 있다고 판단됨.


MaxKeepAliveRequests 

KeepAlive 상태에서 처리할 최대 요청 수로 보통 웹 사이트에서는 100 정도 지정하면 충분.


참고로 개인 블로그가 아닌 정말 접속자가 많은 사이트를 운영할 경우에는 관리상 웹 어플리케이션 서버와 이미지 서버를 분리해 운영해야함

특히, 웹 어플리케이션 서버의 경우에는 KeepAlive Off로 하고 이미지 서버는 연결 유지를 위해 KeepAlive On으로 설정해두기도 함.



반응형