서버가 느려졌어요!
서버를 운영하다가 보면 간혹 눈에 띄게 서버가 느려지는 현상을 경험하게 된다. 시스템에 접근하는 것은 정상인데 웹이 느려졌을 수도 있고 어쩌면 그 반대일 가능성도 있다. 시스템이 느리다는 것은 관리자 혹은 사용자가 요청한 이슈에 대한 응답 속도가 떨어진다는 것을 의미한다. 이는 시스템의 튜닝을 통해 개선할 수도 있으나 시스템의 어느 곳에서 병목현상이 일어나는지를 알아야만 그에 맞게 적절한 조치를 취해 성능을 높일 수 있다. 여기서는 이와 같은 상황에서 시스템의 어느 부분에 대규모 부하가 발생하는지를 점검하는 방법을 살펴보자.
웹이 느려졌어요!
먼저 서버가 느려지는 현상은 크게 웹 접속속도가 느려졌을 때와 시스템 내의 부하로 인해서 느려지는 두 가지 경우로 구분해 살펴볼 수 있다. 시스템의 접속속도는 빠르지만 웹만 느려졌을 경우에는 그 문제점을 찾기가 한층 쉽다. 서비스거부(DoS) 공격 등 외부 요인에 의한 비정상적인 상황을 제외하고 일반적인 상태에서 웹이 느려지는 이유는 크게 3가지 정도로 압축할 수 있다.
가장 대표적인 것이 웹 서버의 로그 크기이다. 아파치 웹 서버를 이용해 웹 서비스를 제공할 때, 웹 로그를 쌓아 놓고 있다면 그 크기를 먼저 살펴보자. 아파치 웹 로그의 최대 크기는 2GB인데 이 용량을 넘으면 웹 서버가 정상적으로 동작하지 않는다. 또한 웹 로그의 크기가 클수록 웹 서버가 열리는 속도도 느려진다. 따라서 로그로 인한 웹속도의 감소를 방지하기 위해서는 로그를 주기적으로 로테이션(rotation)시켜 주는 것이 좋다. 이를 위해서는 여러 가지 방법이 있는데 다음과 같이 24시간에 한 번씩 로그를 로테이션시켜주는 것도 방법이다.
리눅스 1.3.x 버전대 아파치의 로그 로테이션
TransferLog “|/usr/sbin/rotatelogs /usr/local/apache/logs/man-access_log 86400”
2.x 버전대 아파치의 로그 로테이션
CustomLog “|bin/rotatelogs /usr/local/apache/logs/man-access_log 86400”
2.x 버전의 경우 CustomLog ‘|bin/rotatelogs /usr/local/apache /logs/man-access_log 100M’과 같이 로그 크기를 지정해 로테이션할 수도 있다.
만일 로그 크기의 문제가 아니라면 netstat, ps 명령 등을 통해 ‘MaxClients(최대 동시 접속자수)’를 점검해 보자. MaxClients를 150으로 설정해 놓았는데 동시 접속자가 150에 가깝거나 혹은 그 이상이라면 선행된 연결이 끊기기 전까지는 새로운 사용자가 접속되지 않아 웹의 접근속도가 느려진 것처럼 보일 수 있다. 이런 경우에는 서버의 성능에 따라 MaxClients를 적절히 늘려주거나 KeepAlive Timeout(한 번 연결됐던 클라이언트는 다시 연결을 시도할 가능성이 높으므로 KeepAliveTimeout 시간만큼 기다렸다가 그 시간 안에 연결요청이 있으면 새로운 연결을 맺는 시간을(3 way handshake) 절약할 수 있으므로 성능 향상에 도움을 준다. 하지만 여기에 설정된 시간만큼 실제 사용하지 않아도 연결을 맺고 있게 되므로 동시 접속자에 영향을 미치게 된다)을 개별 웹 서비스의 특성을 고려해 적절히 조정하면 웹 접근속도를 높일 수 있다.
마지막으로 웹 서버의 응답속도가 느려질 수 있는 또 다른 경우는 PHP 등의 웹 프로그래밍 내에서 사용하지 않는 잘못된 도메인으로 연결을 시도하는 경우나 해당 페이지의 로드를 요청하는 사용자의 DNS 서버가 오동작을 해 해당 (특정) 도메인을 찾지 못해 시스템의 응답이 느려지는 경우다. 즉 코드 내에 iframe으로 test.co.kr/test /test.php를 불러와서 로딩하는 코드가 있다고 가정할 때, 만일 test.co.kr가 잘못된 도메인이라면 DNS는 test.co.kr에 대해서 resolve를 실시하고, timeout이 발생할 때까지 기다렸다가 응답이 없으면 요청한 사용자에게 없는 도메인이라는 응답을 회신하게 된다. 이처럼 웹 페이지 내에 잘못된 도메인 링크가 많이 걸려 있다면 웹 페이지의 로드속도가 줄어들고 당연히 웹 접속속도가 느려질 것이다. 이 경우에는 해당 도메인을 웹 소스에서 제거해주면 속도가 빨라지며 만일 사용자의 DNS 잘못으로 인해서 도메인을 찾지 못하는 것이라면 사용자 컴퓨터의 DNS를 다른 DNS로 변경해 보는 방법도 있다(참고로 웹 페이지의 호출(접근)은 서버가 가리키는 DNS를 사용하는 것이 아니라 웹 페이지를 호출하는 사용자 컴퓨터에 설정된 DNS를 사용한다).
이 밖에도 직접 접속을 시도하는 사용자와 서버가 있는 네트워크 간의 트래픽이 증가해 느려지는 경우도 있다. 윈도우에서는 tracert 또는 pathping이란 프로그램으로 측정할 수 있으며, 리눅스에서는 traceroute와 pathchar라는 프로그램으로 측정할 수 있다. pathchar (ftp://ftp.ee.lbl.gov/pathchar)라는 프로그램을 처음 들어 본 관리자도 있을 것이다. 이 프로그램은 트레이스(trace)처럼 목적지로 가기 위한 경로를 보여줄뿐만 아니라, 각 경로 사이의 전송속도도 확인해 볼 수 있는 프로그램이다(단 이 때 전송속도는 정확한 것은 아니며 테스트에 의한 대략의 값이다). 하지만 이 프로그램은 속도가 느리고 각 경로 사이의 전송속도 측정을 위해 많은 트래픽을 발생시키므로 실제로 사용하기에는 무리가 있다. <화면 1>은 daum.net으로 pathchar를 시도한 결과이다(2004년에 4월 기준으로 테스트했던 내용이므로 현재 네트워크 속도와는 다를 수 있다).
지금까지 네트워크의 병목현상이나 또는 웹 서버의 설정으로 인해서 웹 응답속도가 느려지는 몇 가지 원인을 살펴봤다. 이제 시스템 내의 부하로 인해 시스템의 응답이 느려지는 경우 병목 지점을 확인하는 방법과 해결 방법에 대해서 알아보자.
구간별 정송 속도 확인
vmstat 1 실행
시스템이 느려졌어요!
시스템 자체가 느릴 경우에 체크해 볼 포인트는 웹과 마찬가지로 대략 3~4개 정도이다. 시스템 자체가 느리다는 것은 어느 프로그램 또는 프로세스가 CPU나 메모리, I/O를 많이 사용하고 있다는 것을 의미하므로 해당 프로그램이나 프로세서를 찾아서 중지 또는 종료시켜야 한다.
먼저 <화면 2>와 같이 vmstat 명령으로 시스템 전체의 리소스 상황을 모니터링한다(<화면 2>를 이해하기 위해서는 <그림 1>과 <표 1>를 참고하면 된다). 이를 통해 어느 곳에서 병목 현상이 발생하고 있는지 점검하고 각 영역에 맞는 대응 방안을 마련하도록 한다.
<그림 1> vmstat의 각 항목별 참고할 부분
<표 1> vmstat의 각 항복별에 대한 설명
구분 |
|
설명 |
proc |
r |
CPU에서 대기 중인 프로세스의 수를 의미한다. 이 값이 증가하거나 r 개수/cpu 개수의 값이 항상 2 이상 나온다면 CPU의 성능을 높여주어야 한다. |
b |
동작하는 블럭 프로세스의 수 이 값이 높다면 블럭 디바이스의 속도를 높여야 한다. |
w |
swap out되는 프로세서의 수이다.w에 값이 증가하면 메모리가 매우 부족하다는 의미이므로 메모리를 늘려야 한다. |
memory(KB) |
swapd |
현대 메모리가 부족해 swap을 사용하고 있는 양을 의미한다. 평소에 이 값이 높다고 해도 free 메모리의 여유가 있다면 메모리가 부족한 것이 아니다. 한번 swap으로 떨어진 프로레스는 메모리의 여유가 생기더라도 CPU에서 다시 호풀하지 않는 한 메모리로 넘어 오지 않는다. |
free |
현재 사용하지 않고 남아 있는 메모리 |
buffer |
버퍼로 사용되고 있는 메모리 양(퍼포먼스에 관련) |
cache |
현재 캐시로 사용되고 있는 메모리 양(퍼포먼스에 관련) |
swap(KB/s) |
si |
디스크에서 메모리로 swap in 되는 양을 의미하며, swap 공간에 있는 데이터를 실제 메모리로호출한다. |
so |
메모리에서 디스크로 swap out 되는 양을 의미하며, 이는 곧 메모리가 부족해 실제 메모리에 있는 데이터를 swap 공간으로 보내는 것이다. |
io(blocks/s) |
bi/bo |
bi는 초당 블럭 디바이스로 보내는 블럭 수이며 bo는 블럭 디바이스로부터 받은 블럭 수이다. 이 두 값이 높다는 것은 I/O 즉 하드디스크에 읽고 쓴느 값이 많다는 것이다. |
system |
in |
초당 인터럽트되는 양이다. 여기에는 time clock과 이더넷의 패킷도 포함되는데 즉 인터럽트의 수가 많다면 네트워크 쪽을 점검해볼 필요가 있다. |
cs |
초당 context switch되는 양이다. CPU에사 실행하는 명령들이 자신의 우선순위보다 높은 명령이 오거나 혹은 자신에게 할당된 CPU 점유 시간이 만료되면 우선순위에서 밀리게 되고 이때 context switch가 발생하게 된다. |
cpu |
us |
유저 프로세스가 CPU를 사용하는 시간 |
sy |
시스템 프로세스가 CPU를 사용하는 시간 |
id |
CPU가 아무 일도 하지 않고 여유 있는 시간 |
<화면 3> top 실행
<화면 4> iostat-x 1 실행
<화면 5> isof 실행
만일 아파치, MySQL 등 서비스를 위해 필요한 프로그램들이 정상적인 방법으로 사용되면서 시스템 리소스를 많이 사용하고 있다면 CPU와 메모리를 증설하거나 더 빠른 디스크로 교체해야 겠지만, 그것이 아니라면 어느 부분에 문제가 있는지 확인해 이를 더 세밀하게 점검해야 한다.
이를 위해서는 top, ps, sar, iostat, netstat 명령 등을 추가로 사용하는데 예를 들어 sar는 10분 간격(기본 값이며 /etc/cron.d/ sysstat에서 수정할 수 있다)으로 모든 시스템 활동 정보(system activity information)를 저장, 수집해 보고하는 기능을 지원해 과거 리소스를 분석하는데 특히 유용하다. 여기에는 매우 많은 정보를 포함하고 있으므로 man sar를 참고하기 바란다.
이밖에도 시스템의 리소스를 분석하는 명령에는 여러 가지가 있다. 예를 들어 vmstat 결과 CPU와 메모리의 사용량이 많을 때는 <화면 3>과 같이 top 또는 ps를 이용해 CPU와 메모리를 많이 사용하는 프로세스를 확인할 수 있으며 이런 프로세스를 확인하면 pid, kill 등을 이용해 해당 process를 종료시킬 수 있다.
만일 vmstat를 통해 모니터링하던 중 I/O의 로드가 많다고 확인되면 iostat -x 1 명령을 통해 어느 디스크에서 사용이 많은지를 확인할 수 있다. <화면 4>를 보면 iostat 출력 결과 /dev/hda3에서 I/O를 많이 사용하는 것을 알 수 있다. 그렇다면 현재 이 I/O에서 어떤 프로그램 혹은 파일이 동작되고 있는지도 살펴보자. <화면 5>처럼 losf 명령을 이용하면 /dev/hda3에서 사용 중인 프로그램과 파일을 볼 수 있으며 이것이 병목을 일으키는 원인이라면 프로그램을 중지시키거나 혹은 pid 번호를 이용해 kill 명령으로 해당 프로세스를 종료시키면 된다.
이 때 만일 IDE 하드디스크를 사용하고 있고 커널에서 DMA (Direct Memory Access)를 지원하도록 설정되어 있다면 hdparm을 이용해서 I/O 버스의 32비트 지원과 DMA를 사용하도록 설정해 I/O의 성능을 향상시킬 수 있으며 병목현상도 줄일 수 있다.
<화면 6> f-prot/usr/sbin 실행
<화면 7> clamscan -i -r/var/qmail/queue/mess/ 실행
바이러스?
그러나 시스템 리소스 분석을 통해서도 그 이유를 찾지 못했다면 바이러스나 웜을 점검해 바이러스에 감염되지 않았는지 확인해보기 바란다. 일반적으로 리눅스는 바이러스에 잘 감염되지 않는다고 알려져 있으나 지난 1998년 이후 리눅스에도 수많은 종류의 바이러스가 등장하고 있다. 대표적인 것이 ELF(Executable and Linking Format) 파일을 감염시키는 RST.B 바이러스다.
여기에 감염된 명령을 실행하면 ELF 바이너리 명령어 파일이 연쇄적으로 감염되고, 다시 이들 명령을 사용하면 해당 명령이 정상적으로 실행되지 않거나 실행 후에도 메모리에서 사라지지 않아 메모리와 CPU를 점유하고 결국 시스템 리소스를 고갈시키게 된다. 또한 바이러스에 감염된 명령을 실행하면 외부의 특정 네트워크로 접속을 지속적으로 시도하는 등 다양한 감염 증상이 나타나 결과적으로 시스템이 느려지게 된다.
리눅스에서 많이 사용하는 바이러스 검색 프로그램에는 f-prot와 clamav가 있다. f-prot(www.f-prot.com) 웹 사이트와 clamav (www.clamav.net) 웹 사이트에서 무료로 다운로드해 사용할 수 있다(단 윈도우에서 사용하려면 비용을 지불해야 한다).
<화면 6>은 f-prot를 이용해 /usr/sbin 아래의 파일을 검색한 화면이다. 바이너리 명령들이 감염된 것을 확인할 수 있다. f-prot는 설치도 간편하고 설치 후 아무런 설정없이 바로 실행이 가능하다는 장점이 있다. <화면 7>은 clamav를 실행해 /var/qmail/queue/mess의 메시지를 점검한 결과다(여기서 탐지된 바이러스는 리눅스 바이러스가 아니라 윈도우 바이러스다).
clamav는 f-prot보다 많은 바이러스 패턴을 가지고 있으며 업데이트 역시 단순한 명령 한 줄로 가능한 것이 특징이다. 파일에 감염된 바이러스, 웜은 물론 메일 프로그램과 연동해 메일로 들어오는 바이러스를 필터링함으로써 바이러스 메일 필터링 프로그램으로 사용할 수도 있다(단 clamav를 사용하기 위해서는 몇 가지 설정 파일을 변경해야 한다).
감염된 파일을 삭제하려면 f-prot는 -delete 옵션, clamav는 --remove 옵션을 추가하면 된다. 단 만일 삭제된 파일이 시스템 명령어이거나 운영상 중요 파일일 경우에는 시스템이 정상적으로 동작하지 않을 수 있으므로 시스템 명령이나 운영상 중요한 파일이 감염된 것을 확인했을 때는 감염되지 않은 동일한 버전의 서버에서 명령어나 중요 파일을 복사해서 덮어쓰거나 rpm 등으로 재설치를 해주는 것이 바람직하다. 그러나 메일 등에서 바이러스나 웜이 검출되면 삭제를 해주는 것이 2차 피해를 막기 위해 바람직하다.
여기서는 시스템이 느려질 때 병목현상을 식별하고 이를 제거하기 위한 방법을 설명하는 것에 초점을 맞추고 있으므로 바이러스에 대해 깊이 설명하지는 않겠다. 그러나 리눅스 서버가 바이러스나 웜에 감염됐다는 것은(메일 제외), 바이러스가 감염된 파일을 다운받아 실행했거나 혹은 외부 침입을 통해 바이러스가 감염된 파일이 실행됐을 가능성이 높다. 따라서 바이러스나 웜 감염이 확인되면 외부 침입에 자주 사용되는 /tmp, /var/tmp, /dev/shm 디렉토리에 이상한 파일이 없는지 그리고 취약한 패스워드는 없는지 웹으로부터의 불법 접속은 없었는지 등을 시스템 로그와 웹 로그를 참조하여 점검해보기 바란다.
지금까지 관리하는 서버가 느려지는 현상이 발생해 시스템을 점검할 때 사용할 수 있는 몇 가지 방법들을 살펴봤다. 이와 병행해 시스템의 성능 향상을 위한 튜닝 방법까지 익혀둔다면 현재 관리하고 있는 리눅스 시스템을 최적의 환경에서 운영할 수 있을 것이다.
출처 : Tong - 낯선남자님의 Linux통