아파치 httpd.conf 수정으로성능최적화 1. 들어가며 2 2. 웹서버성능측정방법 2 가.ab 2 나. Httperf 4 다. Flood - a profile-driven HTTP load tester 5 3. 튜닝이전웹서버성능테스트 6 가. 테스트환경 6 나. 테스트계획 6 다. 테스트케이스 6 4. 아파치기본설치후테스트 6 가.ab 7 나. httperf 8 다.flood 8 5. 환경설정을통한성능최적화 8 가.Timeout 8 나. MaxClients 9 다. KeepAlive 9 라. MaxKeepAliveRequests 9 마. KeepAliveTimeout 9 바. StartServers 9 사. MinSpareServers 10 아. MaxSpareServers 10 자.MaxRequestsPerChild 10 차. HostnameLookups 10 카. 다른설정에서DNS 질의고려 10 타. FollowSymLinks와 SymLinksIfOwnerMatch 10 파.AllowOverride 10 하.EnableMMAP 11 거. EnableSendfile 12 6. 설정변경후테스트 12 가.ab 14 나. httperf 15 다.flood 16 7. 마치며 16 8. 참고자료 17-1-
1. 들어가며 필자는리눅스시스템관리자이다. 시스템관리자란어떤일을하는가? 서버가언제어떻게될지모르는상황에서자기시간이라는 개념이없으며, 끊임없이발생하는취약성들에대한점검과패치, 고객의각종문제들, 손실된데이터복구문제등늘긴장속에서살아가야한다. 시스템관리자라는직업이의미하는바는여기서그치지않는다. 시스템유지보수, 성능관리, 가용성관리, 용량관리, 장애복구등시스템관리자라면대게이 정도의항목들을관리하게된다. 다른분야역시마찬가지이겠지만시스템관리자라는업무는 끊임없는자기개발과노력을요구한다. 이글에서는시스템관리자의이런개발과노력에도움이되고자리눅스로운영하는아파치웹서버의최적화에관해서다루기로한다. 웹서비스의성능최적화는웹서버에서의튜닝과웹브라우져, 웹콘텐츠그리고다른 시스템과의관계등을동시에다루어야하지만자바스크립트, 웹그래픽, HTML, CSS 등의최적화에대한것은이글에서취급하지않는다. 필자는 http://www.websiteoptimization.com/ 에서그런정보들을얻을수있었다. 이글은아파치웹서버의최적화에대해서만다루고있으므로, 그외의다른것들과통합해서 웹서비스성능개선방안을마련하는것은여러분의몫이다. 2. 웹서버성능측정방법 웹사이트가느리면고객은바로다른사이트로이동하기마련이다. 따라서기업은고객을확보, 유지하기위해웹사이트의성능을최상의상태로유지해야하며 이로인해웹사이트의성능을진단하고분석하는도구들에대해서많은관심을가지고있으며현재기업들마다다양한방법들로성능을관리하고있다. 상용 SW WEBest SiteAngel sitemonitor WatchPro/TestPro WEBest 공개 SW ab Flood Httperf Hammerhead Web Performance Tool (WPT) 웹서버의성능을측정하기위해서먼저공개SW 벤치마크프로그램 ab, Flood, Httperf 에대해서알아보기로하자. 가. ab -2-
ab 는 "Apache HTTP server Benchmarking tool" 의약어로서아파치서버의응답속도를측정하는밴치마킹툴이다. 이툴은현재설치된아파치서버의실행속도및성능테스트를위해서제우스테크널리지(Zeus Technology Ltd, http://www.zeustech.net/) 의 Adam Twiss가개발한툴이며. 아파치를설치하고나면기본적으로설치되므로별도의설치과정없이바로사용할수있다. 명령어위치 : /usr/local/apache/bin/ab (RPM 설치시 : /usr/bin/ab) [root@host3 bin]# ab -c 200 -n 1000 -t 10 http://www.superuser.co.kr/ 위에서사용한옵션은 -c( 한번에수행할다중요구수) 값을 200 으로하고, -n( 페이지요청수) 값을 1000 으로하였으며 -t( 테스트허용최대시간) 값을 10 으로주는예이다. 특정사이트의다음과같은정보를확인할수있다. -3-
위의결과를보면다음과같은내용을분석할수있다. Server Software Server Hostname Server Port 아파치버전을표시 특정사이트의이름( 도메인명) 웹서비스사용포트번호 Document Path 초기문서가준재하는웹문서 root위치 Time take for tests 응답시간( 매우중요한결과값임) Document Length 초기문서( 대부분 index.html, index.htm) 의용량크기 Complete requests Failed requests Broken pipe errors Total transferred 요구에응답완료한세션수요구에응답실패한세션수실패한에러수총전송바이트수 HTTP transferred 총전송한 HTML바이트수 Requests per second 초당응답요구수 Time per request 요구에응답한시간( 단위 micro second, 중요한결과값) Time per request Transfer rate 요구에응답한시간 초당전송가능한용량 나. Httperf Httperf 툴은요청이발생하는비율, 총연결수, 타임아웃한계등을제어할수있다. 다운로드는 http://www.hpl.hp.com/research/linux/httperf/ 에서가능하며설치는일반적인소스설치법과동일하게./configure;make;makeinstall 로진행할수있다. 사용할수있는옵션은아래와같다 --server 서버주소 여기에적어준서버로접속을시도한다 --port 숫자 여기에적어준포트로접속을시도한다 --num-conns 숫자총몇개의접속을만들것인지를결정한다. --rate 숫자초당몇개의접속을만들것인지를결정한다. --timeout 숫자숫자만큼의초이후응답이없는연결은 timeout 에러로처리한다. --think-timeout --hog 숫자 CGI등서버쪽에서처리해야하는일들이있는페이지의경우서버측에이를처리할시간을준다. timeout에서이곳에주어진숫자만큼을더한값이진짜 timeout 값이된다. 가능한모든포트를사용한다. 이옵션을주지않으면기본적으로 1024 부터 5000 까지의포트만사용한다. -4-
# httperf --server www.superuser.co.kr --port 80 --num-conns 20000 --rate 1000 --hog 위예제는 www.superuser.co.kr 웹서버의 80번포트로 1초에 1000개씩총 20000개의접속을만들게된다. Flood 는아파치프로젝트하위의프로젝트이다 XML 설정파일을필요로하며, URL 과 POST data 를여러서버들에테스트할수있다. 현재 Flood 는 Subversion 으로관리되고있으며설치시에자동으로소스디렉토리하위에서 apr 과apr-util 패키지를찾으므로아래처럼체크아웃해서설치하면된다. 만일 apr 과 apr-util을이미받아온상태라면 configure 할때 --with-apr and --with-apr-util 옵션을사용해서경로를지정해주면된다 % svn co http://svn.apache.org/repos/asf/httpd/test/trunk/flood %cdflood % svn co http://svn.apache.org/repos/asf/apr/apr/trunk apr % svn co http://svn.apache.org/repos/asf/apr/apr-util/trunk apr-util %./buildconf %./configure --disable-shared %makeall -5-
설치가정상적으로진행되었으면설치한디렉토리에서아래처럼확인할수있다 %./flood examples/round-robin.xml > foo.out 결과파일을다른프로그램에서활용하고싶은경우는 %./examples/analyze-relative foo.out 를실행해보면참고할수있다. analyze-relative 파일은테스트결과값을가공하는간단한스크립트이다. Flood 에대해서보다상세한정보를원한다면방문하자. http://httpd.apache.org/test/flood/faq.html 를 3. 튜닝이전웹서버성능테스트 가. 테스트환경 OS : Red Hat Enterprise Linux AS release 4 (Nahant) Kernel Version : 2.6.9-5.ELsmp CPU & Cache : Memory info Size(MB) Free(MB) Full % Memory : 2026 1877 7% Swap : 4094 4094 0% Web server : Apache Http Server 2.0.52 Web test tool : ab, Httperf, flood 나. 테스트계획 rpm 설치후기본상태에서설치된웹서버에동시접속자 1000 명이 1000 번의요청을하는경우를테스트하여웹서버의성능을측정한다. 다양한환경설정을변경해서웹서버를튜닝한이후다시동일한환경으로테스트해서실제적인성능향상이있는지를점검한다. 다. 테스트케이스 ab -n 1000 -c 1000 -t 10 http://210.183.235.95/ httperf --server 210.183.235.95 --port 80 --rate 1000 --num-conns 20000 --hog flood floodconf..xml > result.out (floodconf.xml 파일에환경설정) -6-
4. 아파치기본설치후테스트 테스트는공정성을위해서공개웹서버벤치마크프로그램종을이용하였으며각각의결 과는아래와같다 가. ab [root@www ~]# ab -c 1000 -n 1000 -t 10 http://210.183.235.95/ This is ApacheBench, Version 2.0.41-dev <$Revision: 1.141 $> apache-2.0 Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/ Server Software: Apache/2.0.52 Server Hostname: 210.183.235.95 Server Port: 80 Document Path: / Document Length: 440 bytes Concurrency Level: 1000 Time taken for tests: 10.6038 seconds Complete requests: 13416 Failed requests: 0 Write errors: 0 Total transferred: 8176434 bytes HTML transferred: 5907440 bytes Requests per second: 1340.79 [#/sec] (mean) Time per request: 745.829 [ms] (mean) Time per request: 0.746 [ms] (mean, across all concurrent requests) Transfer rate: 797.92 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 1 286 1301.0 4 9005 Processing: 21 148 467.1 95 6437 Waiting: 17 135 424.3 87 6434 Total: 57 434 1457.6 108 9703 Percentage of the requests served within a certain time (ms) 50% 108 66% 120 75% 127-7-
80% 135 90% 179 95% 3076 98% 9068 99% 9076 100% 9703 (longest request) 나. httperf [root@www ~]# httperf --server 210.183.235.95 --port 80 --rate 1000 --num-conns 20000 --hog httperf --hog --client=0/1 --server=210.183.235.95 --port=80 --uri=/ --rate=1000 --send-buffer=4096 --recv-buffer=16384 --num-conns=20000 --num-calls=1 Maximum connect burst length: 8 Total: connections 20000 requests 20000 replies 20000 test-duration 20.000 s Connection rate: 1000.0 conn/s (1.0 ms/conn, <=540 concurrent connections) Connection time [ms]: min 0.3 avg 70.5 max 3006.4 median 1.5 stddev 422.3 Connection time [ms]: connect 60.8 Connection length [replies/conn]: 1.000 Request rate: 1000.0 req/s (1.0 ms/req) Request size [B]: 65.0 Reply rate [replies/s]: min 978.7 avg 1000.0 max 1021.5 stddev 17.5 (4 samples) Reply time [ms]: response 9.6 transfer 0.0 Reply size [B]: header 169.0 content 440.0 footer 0.0 (total 609.0) Reply status: 1xx=0 2xx=20000 3xx=0 4xx=0 5xx=0 CPU time [s]: user 3.83 system 14.57 (user 19.2% system 72.9% total 92.0%) Net I/O: 658.2 KB/s (5.4*10^6 bps) Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0 Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0 다. flood [root@www ~]# flood floodconf300.xml > res300.out [root@www ~]#./analyze-relative res300.out Slowest pages on average (worst 5): Average times (sec) -8-
connect write read close hits URL 0.0018 0.0019 0.0081 0.0082 29126 http://210.183.235.95/ Requests: 29127 Time: 0.80 Req/Sec: 41776.74 5. 환경설정을통한성능최적화 가. Timeout 접속된클라이언트가서버에아무런요청이없을때어느정도시간이지나면연결을끊을지를초단위로설정한다. 네트웍의성능이낮을수록이수치를높게설정하는것이좋다. 나. MaxClients 웹서버성능에가장큰영향을주는것은메모리다. 방문자의요청에응답하기위해서프로세스가생성되는되이지시자의개수만큼만생성가능하다. 여기서지정한개수이상의요청이들어오면아파치는요청을무시한다. MaxClients 지시어를조절하여웹서버가스왑을할정도로많은프로세스를만들지않도록해야한다. 스왑은요청당지연시간을늘리기때문에웹서버는스왑을하면안된다.top으로프로세스목록을보고아파치프로세스의평균메모리사용량을알아낸후, 사용가능한메모리의양만큼조절해준다 다. KeepAlive 아파치의한프로세스가접속한클라이언트의지속적인요청작업을계속해서처리하게할것인지를결정하는지시자. 이지시자의값을 On으로되어있어야 MaxKeepAliveRequests, KeepAliveTimeout 지시자가유효하게된다 라. MaxKeepAliveRequests 이전의 KeepAlive 지시어가 On 일때만유효하다. KeepAlive 를이용해서한프로세스가접속한클라인언트의이어지는요청을모두처리하도록설정했는데, 이때무한정계속처리하는것이아니라이지시자를이용해서처리할횟수를지정해준다. MaxKeepAliveRequests 100 처럼설정해두면프로세스가 100번의요청을처리한후자신은죽고그다음프로세스가다시클라인언트의요청을이어서처리하도록하는것이다. 방문자가많은홈페이지라면이값을좀올려두는것이좋다 마. KeepAliveTimeout 이전의 KeepAlive 지시어가 On 일때만유효하다. KeepAlive 를사용한다면프로세스들은이미열린연결에서추가요청을기다리며대기중이다. KeepAliveTimeout 15 처럼설정해두면클라이언트가 15초동안아무요청이없으면프로세스의 연결을끊는다. 이값을 60 초이상으로올리면사용자의요청을기다리며아무일을하지않는 -9-
프로세스가 60 초동안떠있게되는것이다. 자신의네트웍대역과부하에따라적절히조절하자. 기본값 15 로도무방하다 바. StartServers 아파치시작시에실행시킬프로세스의개수. 뒤에나오는 MinSpareServers, MaxSpareServers 등의지시자에의해서프로세스는생성되기도하고죽기도하므로큰의미를가지는것은아니다. 사. MinSpareServers 항상대기하고있을프로세스의최소개수. 여기서지정한숫자보다적은프로세스가대기되어있다면아파치는가능한이숫자를유지하기위해노력한다. 아. MaxSpareServers 항상대기하고있을프로세스의최대개수. 여기서지정한숫자보다많은프로세스가대기되어있다면아파치는가능한이숫자를유지하기위해노력한다. 자. MaxRequestsPerChild 하나의프로세스당최대처리할수있는방문자의요청횟수서버사양이좋다면이값을높여두는것이시스템의부하조절과자원낭비를방지하는데좋다. 차. HostnameLookups 웹서버의로그(access_log) 에보면클라이언트의 IP가기록되어있는데이지시자를 On으로설정하면 IP 주소를도메인명으로기록하기위해서노력을하게된다. 아파치 1.3 이전에 HostnameLookups의기본값은 On 이였다. 이말은접속을요청하면 DNS 를검색해서접속자의호스트명을알아내어야한다는것이다,. 아파치 1.3에서이설정의기본값이 Off 로변경되었다. 아파치의성능을생각한다면반드시 Off 로설정하기바란다. 만일로그파일의주소를호스트명으로변환할필요가있다면아파치에포함된 logresolve 프로그램을사용해서나중에할수있으니실제사용하는웹서버가아닌다른컴퓨터에서로그파일을후처리하길바란다. 카. 다른설정에서 DNS 질의고려 Allow from domain이나 Deny from domain 지시어를사용한다면 ( 즉, IP 주소가아닌호스트명이나도메인명을사용한다면) 부득이중복-역 DNS 검색을 ( 역검색을한후악의로변경되었는지확인하기위해다시검색) 해야한다. 그러므로성능을높이기위해이런지시어에는가능하면이름대신 IP 주소를사용하자 타. FollowSymLinks와 SymLinksIfOwnerMatch -10-
가능하면심볼릭링크를허용하지않는것이보안상좋다. 하지만꼭써야한다면 Options SymLinksIfOwnerMatch 보다는 Options FollowSymLinks를사용하라 Options SymLinksIfOwnerMatch 일경우아파치는심볼릭링크를검사하기위해시스템호출을한번더해야한다. 좋은성능을얻으려면 SymLinksIfOwnerMatch는피하자 파. AllowOverride AllowOverride 는이전에설정된아파치환경설정을무시하고새로운설정을적용하는방법에대한설정이다. AccessFileName 을별도로설정하지않았다면아파치는.htaccess 파일을디렉토리접근인증에사용한다. 설정할수있는지시자는다음과같다. AuthConfig AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile, require 등과같은클라이언트인증지시자의사용을허용. FileInfo AccessFileName 으로지정한파일에대하여 AddEncoding, AddLanguage, AddType, DefaultType, ErrorDocument, LanguagePriority 등과같은문서유형을제어하는지시자 사용을허용 Indexes AccessFileName 으로지정한파일에대하여 AddDescription, AddIcon, AddIconByEncoding, DirectoryIndex, FancyIndexing 등과같은디렉토리인덱싱을제어하는 지시자사용을허용 Limit AccessFileName 으로지정한파일에대하여 allow, deny, order 같은호스트접근을 제어하는지시자사용을허용 Options AccessFileName 으로지정한파일에대하여 Options 지시자를이용한재설정을허용 All 위에서이야기한모든것을허용 None AccessFileName 으로지정한파일을무시. 어떠한설정도재설정할수없다. 만일 overrides를허용한다면아파치는파일명의각부분마다 AccessFileName 으로지정한파일( 대부분.htaccess) 을열길시도한다. 예를들어설정은아래와같고, DocumentRoot /www/htdocs <Directory /> AllowOverride all -11-
</Directory> /index.html URI 에대한요청이있다고가정하자. 아파치는 /.htaccess, /www/.htaccess, /www/htdocs/.htaccess 를매번열려고시도한다. 최고의성능을얻으려면항상 AllowOverride None 을사용하자. 하. EnableMMAP 커널에서메모리매핑(mmap) 을지원한다면아파치가웹문서를로딩하기위하여내부문서를읽을때에파일을메모리매핑하여처리한다. 따라서아파치의성능이크게향상될수있다. 그러나메모리대응이서버의성능을떨어트리고심지어안정성을해치는경우가있고 smp Solaris 서버에서아파치 2.0은종종 mmap 을사용하지않을때가더빠르다. 또한 NFS 마운트한파일시스템에있는파일을메모리대응하는도중에다른 NFS 클라이언트에있는프로세스가파일을지우거나파일크기를줄이면, 웹서버프로세스가다음번에메모리대응한파일내용을읽을때 bus error 가발생할수있다. 위의조건에해당하면전송하는파일을메모리대응하지않도록 EnableMMAP off를사용해야한다. 거. EnableSendfile 아파치는운영체제가 sendfile을지원하면커널 sendfile을사용하여정적파일을서비스하는경우전송할파일을직접읽지않을수있다. sendfile을사용하면 read와 send를따로할필요가없어서매우빨라진다. 그러나 sendfile 을사용하면웹서버의안정성을해치게되는경우가있고, 커널은자신의캐쉬를사용하여 NFS로마운트한파일을안정적으로서비스할수없는경우가있으므로 EnableSendfile off를사용해서파일을sendfile 전송하지않도록할수있다. 6. 설정변경후테스트 -12-
-13-
-14-
가. ab [root@www ~]# ab -c 1000 -n 1000 -t 10 http://210.183.235.95/ This is ApacheBench, Version 2.0.41-dev <$Revision: 1.141 $> apache-2.0 Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/ Benchmarking 210.183.235.95 (be patient) Completed 5000 requests Completed 10000 requests Finished 14033 requests Server Software: Apache/2.0.52 Server Hostname: 210.183.235.95 Server Port: 80 Document Path: / Document Length: 440 bytes -15-
Concurrency Level: 1000 Time taken for tests: 10.61616 seconds Complete requests: 14033 Failed requests: 0 Write errors: 0 Total transferred: 8608215 bytes HTML transferred: 6219400 bytes Requests per second: 1394.71 [#/sec] (mean) Time per request: 716.997 [ms] (mean) Time per request: 0.717 [ms] (mean, across all concurrent requests) Transfer rate: 835.45 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 2 162 961.7 18 9049 Processing: 16 126 385.1 94 6459 Waiting: 13 114 383.5 81 6439 Total: 52 288 1147.4 118 9890 Percentage of the requests served within a certain time (ms) 50% 118 66% 123 75% 128 80% 132 90% 153 95% 175 98% 3139 99% 9188 100% 9890 (longest request) 나. httperf [root@www ~]# httperf --server 210.183.235.95 --port 80 --rate 1000 --num-conns 20000 --hog httperf --hog --client=0/1 --server=210.183.235.95 --port=80 --uri=/ --rate=1000 --send-buffer=4096 --recv-buffer=16384 --num-conns=20000 --num-calls=1 Maximum connect burst length: 14 Total: connections 20000 requests 20000 replies 20000 test-duration 19.999 s Connection rate: 1000.0 conn/s (1.0 ms/conn, <=37 concurrent connections) Connection time [ms]: min 0.5 avg 3.1 max 47.3 median 1.5 stddev 4.6 Connection time [ms]: connect 1.0 Connection length [replies/conn]: 1.000-16-
Request rate: 1000.0 req/s (1.0 ms/req) Request size [B]: 65.0 Reply rate [replies/s]: min 996.2 avg 1000.0 max 1004.0 stddev 3.4 (4 samples) Reply time [ms]: response 2.1 transfer 0.0 Reply size [B]: header 150.0 content 440.0 footer 0.0 (total 590.0) Reply status: 1xx=0 2xx=20000 3xx=0 4xx=0 5xx=0 CPU time [s]: user 2.95 system 10.76 (user 14.8% system 53.8% total 68.6%) Net I/O: 639.7 KB/s (5.2*10^6 bps) Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0 Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0 다. flood [root@www ~]# flood floodconf300.xml > res300.out [root@www ~]#./analyze-relative res300.out Slowest pages on average (worst 5): Average times (sec) connect write read close hits URL 0.0019 0.0020 0.0045 0.0046 28999 http://210.183.235.95/ Requests: 28999 Time: 0.45 Req/Sec: 65931.82 7. 마치며 3가지벤치마크프로그램들의결과가모두동일하게나타나지는않지만테스트결과들은설정을변경하기이전보다전부향상된것을확인할수있다. ab httperf flood 기본상태 Time per request: 745.829 [ms] Reply time [ms]: response 9.6 Time: 0.80 sec 튜닝이후 Time per request: 716.997 [ms] Reply time [ms]: response 2.1 Time: 0.45 sec 몇몇웹디자이너들은사용자들이빠른사이트를원하는사실을간혹잊기도한다그렇게만들어지는웹서버의콘텐츠들이웹서버를느리게만들기도하고혹은네트워크의병목현상과서버의로드로인해느려질수도있다웹서버의최적화는아파치의설정이외에다양한요소에의해영향을받지만필자는일단이글에서여러분이리눅스서버관리자로서적어도아파치는빠르게설정할수있기를바란다이외에도여러분은아파치성능향상을위해서를이용한생략법을 -17-
사용한콘텐츠압축 모듈을이용한이미지캐싱등을이용할수있다 처음에이야기한것처럼다른것들과통합된환경에서웹서비스의성능개선방안을마련하는것은글을읽는여러분의몫이다 8. 참고자료 서비스 리눅스서버관리실무바이블웹서버성능테스트툴소개웹사이트성능분석웹서버성능테스트아파치서브프로젝트아파치밴치마킹툴 -18-