[server] Apache가 MaxClient에 도달하고 서버 잠금

나는 현재 아파치 서버가 실행이 mpm-preforkmod_php512M 실제 / 1024M burstable RAM과 오픈 VZ VPS (NO 스왑)에. 일부 테스트를 실행 한 후 Apache가 얻는 최대 프로세스 크기는 23M이므로 MaxClients25로 설정 했습니다 (23M x 25 = 575MB, 나에게 좋습니다). 내 서버에서 일부로드 테스트를 실행하기로 결정했고 결과가 당황했습니다.

내가 사용하고 ab워드 프레스 블로그의 메인 페이지를 요청 내 데스크탑 컴퓨터에.

ab24 개의 동시 연결로 실행하면 모든 것이 정상으로 보입니다. 물론, CPU는 올라가고, 여유 RAM은 내려갑니다. 결과는 요청 당 약 2-3 초의 응답 시간입니다.

그러나 ab25 개의 동시 연결 (서버 제한)로 실행 하면 몇 초 후에 Apache가 중단됩니다. 요청 처리를 시작한 다음 응답을 중지하고 CPU가 100 % 유휴 상태로 돌아가 ab시간 초과됩니다. 아파치 로그에 도달했다고합니다 MaxClients.

이런 일이 발생하면 Apache는 25 개의 실행중인 프로세스 (서버 상태를 확인하면 모두 “W”에 있음)로 TimeOut고정되어 프로세스가 종료되고 서버가 다시 응답하기 시작한 후에 만 설정됩니다 (제 경우에는 설정되어 있습니다) ~ 45).

내 질문 : 예상되는 동작입니까? 왜 아파치가 도착했을 때 죽는가 MaxClients? 24 개의 연결로 작동하는 경우 25와 작동하지 않아야합니다. 각 요청에 응답하는 데 더 많은 시간이 걸리고 나머지는 대기열에 넣는 것입니까?

실행중인 모든 어린이 ab가 서버에 동시 연결을 설정하여 웹 서버를 죽일 수 있다는 것은 다소 이상하게 들립니다 MaxClients.



답변

하아! 나는 마침내 문제를 스스로 발견했다. 그것은 서버 관리자보다 프로그래밍과 관련이 있지만, 어쨌든 여기에 답을두기로 결정했습니다 .Google을 검색하여 그런 종류의 문제가있는 유일한 사람이 아니라는 것을 알았습니다 (아파치가 멈 추면 첫 번째 추측은 문제가 있다는 것입니다) 서버와 함께).

이 문제는 Apache가 아니라 WordPress와 관련이 있습니다. 더 구체적으로 내 테마로. Lightworld라는 테마를 사용하고 있으며 블로그 헤더에 이미지 추가를 지원합니다. 이를 위해 PHP의 함수를 사용하여 이미지 크기를 확인합니다 getimagesize(). 이 함수는 이미지를 얻기 위해 서버에 대한 또 다른 http 연결을 열기 때문에 각 요청 ab은 PHP에서 내부적으로 다른 요청을 작성했습니다. 서버에서 사용할 수있는 모든 슬롯을 사용하면서 이러한 PHP 요청이 대기열에 들어 갔지만 Apache 내부 프로세스가 슬롯이 PHP 내부 요청을 완료하기를 기다리는 원래 요청으로 프로세스가 잠겨 있기 때문에 아파치에 도달 할 수 없습니다.

기본적으로 PHP는 서버를 교착 상태로 만들고 있었고 Apache는 이러한 연결이 “자식”요청을 기다리는 시간이 초과 된 후에 만 ​​정상적으로 작동하기 시작했습니다.

테마에서이 기능을 제거한 후에 ab는 원하는만큼의 동시 연결로 서버를 사용할 수 있으며 Apache가 예상대로 대기열을 대기 중입니다.


답변

여기서 발생하는 것은 25 개의 스레드가 연결을 수락 할 수 있고 26 개의 동시 요청을 보내는 것입니다. 마지막 요청은 백 로그의 크기에 따라 소켓 큐에 있습니다.

두 번째 문제는 실행중인 모든 것이 2-3 초 걸리는 25 개의 동시 연결이 속도를 늦추는 데 충분히 오래 걸리는 것입니다. sleep (1)은 작동하지만 mysql에서 파일 잠금 또는 테이블 잠금을 수행하는 경우 각 병렬 요청은 45 초 시간 초과에 도달 할 때까지 완료되기 전에 대기 할 수 있습니다.

23MB는 mod_php와 모듈이로드 된 아파치 프로세스의 경우 작게 들리므로 응용 프로그램이 실행될 때 해당 아파치 프로세스가 약간 더 많은 램을 사용하는 것을 볼 수 있습니다. MaxClients와 메모리를 사용하여 실제로 수학을 할 수는 없지만 다소 가깝지만 결코 알 수 없습니다.

www-data  1495  0.1  0.9  56288 19996 ?        S    15:48   0:01 /usr/sbin/apache2 -k start
www-data  1500  0.0  0.5  49684 12436 ?        D    15:48   0:00 /usr/sbin/apache2 -k start

하나의 시스템, 56M 및 49M 프로세스가 있습니다.

다른 기계 :

www-data  7767  0.1  0.1 213732 14840 ?        S    14:55   0:08 /usr/sbin/apache2 -k start
www-data  8020  0.2  0.1 212424 13660 ?        S    14:57   0:08 /usr/sbin/apache2 -k start

다른 기계 :

www-data 28509  0.8  0.1 161720 10068 ?        S    14:39   0:43 /usr/sbin/apache2 -k start
www-data 28511  0.8  0.1 161932 10344 ?        S    14:39   0:43 /usr/sbin/apache2 -k start

따라서 메모리 사용은 어떤 모듈이로드되는 작업에 따라 크게 달라집니다. 마지막 두 가지에서는 응용 프로그램에서 사용하지 않기 때문에 pdo & pdo_mysql을 비활성화했다고 생각합니다.

진짜 질문은, 당신이하는 일이 3 초 걸리는 것입니다. 오늘날의 세계에서 그것은 영원하며 ‘차단’애플리케이션으로 간주됩니다. Apache는 일반적으로 죽지 않지만 서비스를 제공 할 수 있거나 대기 요청이 시간 초과 될 때까지 해당 스레드를 백 로그 큐에 남겨 둡니다. 응용 프로그램이 아마도 아파치 시간 초과를 유발하고 있다고 생각합니다. phpinfo ();를 포함하는 페이지에서 시도하십시오. 결과가 같은지 확인하십시오.


답변