Media Log

가끔 접속자가 많은 서버를 운영하다 보면 갑자기 웹 접속이 되지 않거나 접속이 너무 느려
아파치 데몬 개수를 확인해 보면 httpd가 256개나 떠 있는 경우가 있다.

그럼 먼저 웹서버가 갑자기 느려질 경우를 보자.
기본적으로 아파치 웹 서버의 경우 Max Clients가 256으로 설정되어 있어 동시에
256개의 데몬이 뜨게 되면 더 이상의 접속을 받아들이지 않고, 기존의 프로세스가
죽을 때까지 대기한 후 접속이 끊기게 되면 그제서야 접속을 받아들이게 된다.

따라서 동시 접속이 많은 경우에는 이전의 웹 접속이 끊길 때까지 대기해야 하므로 접속 속도가
느린 것처럼 느끼게 되는 것이다. 아래의 명령으로 동시접속을 체크 해보자

# netstat -anp | grep :80 | grep ESTAB | wc -l

또, 일반적으로 정상적인 접속의 경우에 256개의 프로세스가 모두 뜨는 경우는 그리 많지 않기에
현재의 상태가 비정상적인 접속인지 여부를 판단해야 한다.
이를 판단할 수 있는 방법은

# netstat -na | grep ES

ESTABLISHED된 연결 상태를 확인하여 클라이언트의 IP가 정상적인 연결인지 여부를 확인하면 된다. 또는

# netstat -na | grep ES | awk '{print $5}' | sort

클라이언트의 IP만 따로 확인해 봐도 된다.

통상적으로 HTTP 1.1 규약에서부터 적용되기 시작한 KeepAlive 기능을 지정하였을 경우
한 클라이언트 IP에서 동시에 3~5개 정도의 ttp 프로세스를 생성하므로 한 IP에서 3~5개 정도의
프로세스를 생성하는 것은 정상적인 현상이다. 그렇지 않고 여러개의 프로세스가 떠 있다면
비정상적인 접속 또는 부하를 일으키는 원인을 찾아봐야 할 것이다.

일단 top 명령을 이용하여 CPU 점유를 많이 하고 있는 프로세스들을 찾아야 할 것이다

# top -d 2

또는 잘못 짜여진 cgi 프로그램으로 인하여 시스템의 메모리를 몽땅 소비하는 프로그램이
실행 되고 있는지 살펴봐야 한다.

그리고 웹집이나 텔레포드 등의 로봇들이 접근하면 시스템은 현저하게 느려질 것 이다.
이러한 점들도 대비하여야 한다. 또한 스트리밍 서비스로 인한 부하도 점검해봐야 할 것 이다.

이번에는 웹서버가 정지되는 경우를 살펴보자.
MaxClient 에 걸려 서버가 정지되는 경우가 발생 할 수 있다.
참고로 엊그제 새벽에 한참 맛있게(?) 자고 잇는데 이런 경우를 당했다 ㅡㅡ;

MaxClient 수치는 아파치 소스코드에서 초기 설정값이 설정되어 있기 때문에 아무리 수치를 올려
설정을 하여도 아파치 웹서버는 동시에 httpd 데몬은 256개 이상 생성할 수 없다.
동시에 256개의 데몬이 뜨게 되면 더 이상의 접속을 받아들이지 않고, 기존의 프로세스가
죽을 때까지 대기한 후 접속이 끊기게 되면 그제서야 접속을 받아들이게 된다.

그럼 어떻게 해야 할 것인가?

일단은 아파치 세팅 시 Max Client 수치를 올리도록 소스코드를 수정하면 된다.
아파치 소스를 보면 src/include 안에 httpd.h 라는 헤더파일이 있는데 HARD_SERVER_LIMIT
값이 256으로 정의되어 있다.

#ifndef HARD_SERVER_LIMIT
#ifdef WIN32
#define HARD_SERVER_LIMIT 1024
#elif defined(NETWARE)
#define HARD_SERVER_LIMIT 2048
#else
#define HARD_SERVER_LIMIT 256
#endif
#endif

윈도우는 1024 넷웨어는 2048 기타는 256으로 설정이 되어있는것을 볼 수 있다. 리눅스는 기타에 속한다..ㅋㅋㅋ
그럼 256의 수치를 변경한 다음 컴파일 하면 된다. 이것은 수치는 시스템 사양에 따른 적절한
조절이 필요하다. 되도록 4의 배수로 수치를 조정하길 바란다.

일단 셋팅을 이렇게 하였다면 적어도 Max Clients 에 걸려 웹서버가 정지당하는 일은 없을것이다.
하지만 그냥 귀차니즘으로 인하거나 서버사양이 좋지 않아 디폴트로 셋팅하였다면
아파치 설정파일에서 소한의 설정을 하여야 한다.

이는 웹서버가 느려지는 것과 다운되는 것에 대한 최소한의 노력이라고 생각하면 된다.

일단 Timeout 값의 수치를 변경하자.
이 값은 클라이언트에서 서버에 연결하엿을때 클라이언트와 서버간에 아무런 메세지가 발생하지
않았을 때 오류로 처리할 시간을 설정한 값이다.
보통 300으로 설정되어있다. 만약 네트워크 속도가 느리다면 수치를 조금 올려서 설정하는 것이 좋다.

다음은 MaxKeepAliveRequests 의 값을 수정하여야 한다.
이 값의 의미는 연결을 유지한체로 허용할 수 있는 최대 요구수를 나타낸다.
이 값이 0 이라면 제한하지 않는다는 의미가 되고 일반적으로 이 수치는 높게 설정하는 것이 좋다.

다음 KeepAliveTimeout 의 수치를 변경하자. 이 값은 동일한 방문자가 동일한 연결을 유지한 채로 다음
요청을 할 때 까지 연결을 유지한 채로 기다리는 시간을 허용하는 시간을 의미한다.
따라서 접속자가 많다면 클라이언트에서 설정시간내에 요청을 하지 않으면 연결을 끊음으로서 요청시
생성되었던 데몬을 Kill 할 수 있다.

이정도로 웹서버의 성능을 튜닝하엿다.
나머지 무한한 추가적인 기능은 각자 상황에 맞게 설정 할 수 있을것이다.