나는 (우리를 위해) 많이로드 된 웹 서버에서보고있는 일부 서버 성능 문제를 이해하려고합니다. 환경은 다음과 같습니다.
- 데비안 레니 (모든 안정적인 패키지 + 보안 업데이트로 패치)
- 아파치 2.2.9
- PHP 5.2.6
- Amazon EC2 대형 인스턴스
우리가보고있는 행동은 일반적으로 웹이 반응을 느끼지만 요청 처리를 시작하는 데 약간의 지연이 발생한다는 것입니다. 피크 사용량이 최대 1 ~ 2 초, 때로는 2 ~ 3 초입니다. 서버의 실제로드는 매우 높은 것으로보고되고 top
있습니다 ( 보통 10.xx 또는 20.xx) . 또한이 시간 동안 (조차 vi
) 서버에서 다른 작업을 실행하는 것은 매우 느리므로로드가 확실히 증가합니다. 이상하게도 Apache는 초기 지연 이외의 반응을 유지합니다.
prefork를 사용하여 Apache를 다음과 같이 구성했습니다.
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
그리고 KeepAlive는
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
서버 상태 페이지를 보면,로드가 심한이시기에도 일반적으로 80-100 개의 요청과 keepalive 상태의 많은 요청을 처리하는 클라이언트 용량에 거의 도달하지 않습니다. 그것은 초기 요청 속도 저하를 “핸들러를 기다리는 중”으로 배제하라고 말하지만 틀릴 수도 있습니다.
Amazon의 CloudWatch 모니터링에 따르면 OS가 15보다 큰로드를보고하더라도 인스턴스 CPU 사용률은 75-80 %입니다.
의 출력 예 top
:
top - 15:47:06 up 31 days, 1:38, 8 users, load average: 11.46, 7.10, 6.56
Tasks: 221 total, 28 running, 193 sleeping, 0 stopped, 0 zombie
Cpu(s): 66.9%us, 22.1%sy, 0.0%ni, 2.6%id, 3.1%wa, 0.0%hi, 0.7%si, 4.5%st
Mem: 7871900k total, 7850624k used, 21276k free, 68728k buffers
Swap: 0k total, 0k used, 0k free, 3750664k cached
프로세스의 대부분은 다음과 같습니다.
24720 www-data 15 0 202m 26m 4412 S 9 0.3 0:02.97 apache2
24530 www-data 15 0 212m 35m 4544 S 7 0.5 0:03.05 apache2
24846 www-data 15 0 209m 33m 4420 S 7 0.4 0:01.03 apache2
24083 www-data 15 0 211m 35m 4484 S 7 0.5 0:07.14 apache2
24615 www-data 15 0 212m 35m 4404 S 7 0.5 0:02.89 apache2
vmstat
위와 동시에 출력 예 :
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
8 0 0 215084 68908 3774864 0 0 154 228 5 7 32 12 42 9
6 21 0 198948 68936 3775740 0 0 676 2363 4022 1047 56 16 9 15
23 0 0 169460 68936 3776356 0 0 432 1372 3762 835 76 21 0 0
23 1 0 140412 68936 3776648 0 0 280 0 3157 827 70 25 0 0
20 1 0 115892 68936 3776792 0 0 188 8 2802 532 68 24 0 0
6 1 0 133368 68936 3777780 0 0 752 71 3501 878 67 29 0 1
0 1 0 146656 68944 3778064 0 0 308 2052 3312 850 38 17 19 24
2 0 0 202104 68952 3778140 0 0 28 90 2617 700 44 13 33 5
9 0 0 188960 68956 3778200 0 0 8 0 2226 475 59 17 6 2
3 0 0 166364 68956 3778252 0 0 0 21 2288 386 65 19 1 0
마지막으로 Apache의 출력 server-status
:
Server uptime: 31 days 2 hours 18 minutes 31 seconds
Total accesses: 60102946 - Total Traffic: 974.5 GB
CPU Usage: u209.62 s75.19 cu0 cs0 - .0106% CPU load
22.4 requests/sec - 380.3 kB/second - 17.0 kB/request
107 requests currently being processed, 6 idle workers
C.KKKW..KWWKKWKW.KKKCKK..KKK.KKKK.KK._WK.K.K.KKKKK.K.R.KK..C.C.K
K.C.K..WK_K..KKW_CK.WK..W.KKKWKCKCKW.W_KKKKK.KKWKKKW._KKK.CKK...
KK_KWKKKWKCKCWKK.KKKCK..........................................
................................................................
제한된 경험으로 다음과 같은 결론 / 질문을 도출했습니다.
-
너무 많은
KeepAlive
요청을 허용 할 수 있습니다 -
일관성이없고 많지는 않지만 vmstat에서 IO를 기다리는 데 시간이 걸린다는 것을 알 수 있습니다. (생각합니까?) 이것이 큰 관심사인지 확실하지 않습니다.
-
또한 vmstat에서 일부 반복에서 많은 프로세스가 제공되기를 기다리고 있음을 알았습니다. 이는 웹 서버의 초기 페이지로드 지연을 잘못으로 인한 것입니다.
-
우리는 정적 컨텐츠 (75 % 이상)와 스크립트 컨텐츠를 혼합하여 제공하며, 스크립트 컨텐츠는 종종 프로세서 집약적이므로 둘 사이의 올바른 균형을 찾는 것이 중요합니다. 장기적으로 두 서버를 최적화하기 위해 다른 곳으로 스태틱을 옮기고 싶지만 현재 우리 소프트웨어는 그 준비가되어 있지 않습니다.
누구든지 아이디어가 있다면 추가 정보를 제공하게되어 기쁩니다. 다른 메모는 이것이 고 가용성 프로덕션 설치이므로 조정 후 조정하는 것을주의하고 KeepAlive
값 자체 와 같은 것을 가지고 놀지 않은 이유입니다. 아직.
답변
나는 클라우드에서 물건을 실행하는 것에 대해별로 신경 쓰지 않는다는 것을 인정하면서 시작할 것입니다. 그러나 다른 곳에서의 경험을 바탕 으로이 웹 서버 구성은 상당히 적은 양의 트래픽을 반영한다고 말하고 싶습니다. Runqueue가 너무 크다는 것은 처리 할 수있는 CPU가 충분하지 않다는 것을 나타냅니다. Runqueue에 무엇이 더 있습니까?
너무 많은 KeepAlive 요청을 허용 할 수 있습니다
아니오-keeplive는 여전히 성능을 향상 시키며, 최신 브라우저는 파이프 라인 시간과 요청을 병렬로 실행할시기를 아는 것에 대해 매우 현명합니다 .5 초의 시간 초과는 여전히 높으며 대기중인 서버 가 많습니다. 매우 큰 대기 시간 문제가 발생했습니다. 이것을 2-3으로 낮추는 것이 좋습니다. 실행 시간이 약간 단축됩니다.
웹 서버에 이미 mod_deflate가 설치되어 있지 않다면 그렇게하는 것이 좋습니다. ob_gzhandler ()를 PHP 스크립트에 추가하십시오. 이 작업을 자동 사전 추가로 수행 할 수 있습니다.
if(!ob_start("ob_gzhandler")) ob_start();
(예, 압축은 더 많은 CPU를 사용하지만 서버를 실행 대기열에서 더 빨리 가져 오거나 적은 TCP 패킷을 처리하여 전체적으로 CPU를 절약해야합니다. 또한 보너스로 사이트도 더 빠릅니다).
MaxRequestsPerChild의 상한을 설정하는 것이 좋습니다. 500과 같은 것을 말하십시오. 이것은 어딘가에서 메모리 누수가 발생하는 경우 프로세스에 약간의 전환을 허용합니다. httpd 프로세스는 거대해 보입니다. 필요하지 않은 아파치 모듈을 제거했는지 확인하고 올바른 캐싱 정보로 정적 컨텐츠를 제공하고 있는지 확인하십시오.
여전히 문제가 발생하면 PHP 코드에 문제가있을 수 있습니다 (fastCGI를 사용하도록 전환하는 경우 큰 성능 저하없이 분명히 나타납니다).
최신 정보
정적 콘텐츠가 페이지마다 크게 다르지 않으면 다음과 같이 실험 해 볼 가치가 있습니다.
if (count($_COOKIE)) {
header('Connection: close');
}
PHP 스크립트에서도 마찬가지입니다.
답변
W 상태의 많은 프로세스도 상당히 높기 때문에 비동기 리버스 프록시 설치를 고려해야합니다. Apache 프로세스는 네트워크에서 차단 된 클라이언트를 통해 느린 클라이언트로 컨텐츠를 보내는 데 많은 시간을 소비하는 것으로 보입니다. Apache 서버의 프론트 엔드 인 Nginx 또는 lighttpd는 W 상태의 여러 프로세스를 크게 줄일 수 있습니다. 그렇습니다. 많은 keepalive 요청을 제한해야합니다. Keepalive를 끄려고 시도하는 것이 좋습니다.
BTW, 107 Apache 프로세스는 22rpm에 비해 너무 높으며 5 개의 Apache 프로세스 만 사용하여 100-120rps를 제공 할 수있었습니다. 아마도 다음 단계는 응용 프로그램을 프로파일 링하는 것입니다.
답변
vmstat에는 CPU 대기 시간이 상당히 높다는 것을 나타내는 두 개의 행이 있으며 그 주위에서 상당한 수의 쓰기 (io-bo) 및 컨텍스트 전환을 수행합니다. 블록 작성 내용과 대기 시간을 제거하는 방법을 살펴 보겠습니다. 디스크 IO를 개선 할 때 가장 많이 개선 될 수 있다고 생각합니다. syslog 확인-비동기 쓰기로 설정하십시오. 컨트롤러의 쓰기 캐시가 작동 중인지 확인하십시오 (배터리가 불량 일 수 있음).
Keepalive는 성능 문제를 일으키지 않으므로, 앞에서 캐시를 실행하지 않으면 연결 설정 시간을 절약 할 수 있습니다. MaxSpareServers가 약간 충돌하여 위기에 처할 때 모든 포크를 기다리지 않을 수 있습니다.
답변
첫 번째 시도로 keepalive를 끄는 것을 고려해야합니다 …
107 요청이 처리되면 MaxSpareServers를 설정 한 것보다 높게 유지합니다 …
정적 컨텐츠에 대한 리버스 프록시로서 장기 nginx의 IMHO를 고려해야합니다.
답변
첫 번째 제안 : Keepalives를 비활성화하십시오. 성능이 향상 된 특정 상황을 식별 할 수있을 때만 필요했지만 일반적으로 Keepalive를 사용하면 요청 / 초가 감소했습니다.
두 번째 제안 : MaxRequestsPerChild를 설정하십시오. 여기서 symcbean을 에코하면 메모리 누수의 경우 프로세스 롤오버에 도움이됩니다. 500은 좋은 출발점입니다.
세 번째 제안 : MaxClients를 늘리십시오. 이에 대한 야구장 계산은 각 httpd 프로세스의 (실제 메모리-httpd가 아닌 프로세스에서 사용하는 메모리) / 크기입니다. httpd가 어떻게 컴파일되었는지에 따라이 숫자는 255입니다. 공용 서버에 250을 사용하여 시스템을 크롤링하는 google / yahoo / MS를 처리합니다.
넷째 제안 : MaxSpareServers를 증가 시키십시오 : 4-5x MinSpareServers와 같은 것.
이러한 제안에 실패하면 리버스 프록시 또는 memcache for DB를 사용한로드 밸런싱을 살펴볼 것입니다.